This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

# removes all variables but NOT functions
rm(list = setdiff(ls(), lsf.str()))
knitr::opts_chunk$set(echo = FALSE)
library(magrittr)
library(ggplot2)
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(ggplot2)
library(lme4)
Loading required package: Matrix
library(tidyr)

Attaching package: ‘tidyr’

The following object is masked from ‘package:Matrix’:

    expand

The following object is masked from ‘package:magrittr’:

    extract
library(merTools) 
Loading required package: arm
Loading required package: MASS

Attaching package: ‘MASS’

The following object is masked from ‘package:dplyr’:

    select


arm (Version 1.9-3, built: 2016-11-21)

Working directory is /Users/djw/Dropbox/PROGRAMMING/_NEURO/2017_MADE/Analysis
library(lsr)
library(reshape2)

Attaching package: ‘reshape2’

The following object is masked from ‘package:tidyr’:

    smiths
library(ggpubr)
library(plyr)
--------------------------------------------------------------------------------------------------------------------
You have loaded plyr after dplyr - this is likely to cause problems.
If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
library(plyr); library(dplyr)
--------------------------------------------------------------------------------------------------------------------

Attaching package: ‘plyr’

The following objects are masked from ‘package:dplyr’:

    arrange, count, desc, failwith, id, mutate, rename, summarise, summarize
library(Hmisc) # cut2
Loading required package: lattice
Loading required package: survival
Loading required package: Formula

Attaching package: ‘Hmisc’

The following objects are masked from ‘package:plyr’:

    is.discrete, summarize

The following objects are masked from ‘package:dplyr’:

    combine, src, summarize

The following objects are masked from ‘package:base’:

    format.pval, round.POSIXt, trunc.POSIXt, units
library(RColorBrewer)
specify_decimal <- function(x, k) trimws(format(round(x, k), nsmall=k))

Image Swap Version

Analysis of the MULTIPLIER trials first

still need to work out how to select subject if the NM trials based on their performance in the multiplier trials

Dataframe header

# set WD
setwd("~/Dropbox/PROGRAMMING/_NEURO/2017_MADE/Analysis")
load("Data/S_M.Rdata")
load("Data/S_M_raw.Rdata")
load("Data/NS_M.Rdata")
load("Data/S_NM.Rdata")
load("Data/S_NM_raw.Rdata")
head(S_M_raw)
mean(S_NM$rt)
mean(S_NM$accuracy)
mean(S_NM$swapAmount)

mean(S_M$rt)
mean(S_M$accuracy)
sd(S_M$accuracy)
mean(S_M$swapAmount)


subject_means <- group_by(S_M_raw, subject) %>%
  dplyr::summarize(swaps = mean(swapAmount, na.rm =T))
plot(subject_means)

subject_means <- group_by(S_M_raw, subject) %>%
  dplyr::summarize(rt = mean(rt, na.rm = T), finalEarnings = mean(finalEarnings, na.rm = T))

Table of subject count, mean, median, SD, range, skew, kurtosis

Experiment 1/2

Accuracy, rt

Uncleaned/Cleaned
load("Data/made_descripive_stats.Rdata")

Add all DFs (cleaned), mark by condition

Plot boxplots of rt and accuracy

load("Data/NS_NM.Rdata")
load("Data/NS_M.Rdata")
load("Data/S_NM.Rdata")
load("Data/S_M.Rdata")
NS_NM$type = "NoSwap_NoMult"
NS_M$type = "NoSwap_Mult"
S_NM$type = "Swap_NoMult"
S_M$type = "Swap_Mult"
# Join all DFs
common <- intersect(names(NS_NM), names(NS_M))
df = rbind(NS_NM[,common], NS_M[,common])
common <- intersect(names(S_NM), names(S_M))
df2 = rbind(S_NM[,common], S_M[,common])
common <- intersect(names(df), names(df2))
df_full = rbind(df[,common], df2[,common])
# Boxplot RT
boxplot(rt ~ factor(type),
        varwidth = TRUE, xlab = "Trial Type",
        main = "RT by Trial Type", ylab = "RT in s", data = df_full)

# Barplot of Accuracy
#First get means for each trial condition (type) by Subject
d <- df_full
subject_means <- group_by(d, type) %>%
  dplyr::summarize(accuracy = mean(correct, na.rm = T))
subject_means$accuracy = round(subject_means$accuracy, 3)
#PLOT
lower=c(0.787990, 0.787694, 0.798404, 0.759005) 
upper=c(0.877638, 0.867699, 0.880029, 0.893729)
barplot <- ggplot(subject_means, aes(x = type, y = accuracy)) +
  stat_summary(
    geom = "bar",
    fun.y = "mean",
    col = "black",
    fill = "gray70"
  ) +
  #geom_point(position = position_jitter(h = 0, w = 0.2)) +
  scale_y_continuous(limits = c(0, max(d$correct, na.rm = T)),
                     expand = c(0, 0)) +
  geom_text(aes(label=accuracy), position=position_dodge(width=0.9), vjust=-0.25, hjust=-0.65) +
  geom_errorbar(data=subject_means, mapping=aes(x=type, ymin=upper, ymax=lower), width = 0.3)
barplot + ggtitle("Accuracy by Trial Type")

T-Test NS_M vs S_M accuracy

t.test(NS_M$correct, S_M$correct)

t.test(NS_NM$rt[NS_NM$Trial<51], NS_NM$rt[NS_NM$Trial>50])

subject_means <- group_by(S_M_raw, subject) %>%
  dplyr::summarize(swapAvg = mean(swapAvg), finalEarnings = mean(finalEarnings, na.rm = T))
x = subject_means$swapAvg[subject_means$swapAvg>1.6]
length(x)
length(subject_means$subject)

T-test NS vs S RT

t.test(subject_means$rt[subject_means$study == "Standard Mult."], subject_means$rt[subject_means$study=="Swap Mult."])

    Welch Two Sample t-test

data:  subject_means$rt[subject_means$study == "Standard Mult."] and subject_means$rt[subject_means$study == "Swap Mult."]
t = -2.8654, df = 35.986, p-value = 0.006914
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.1442602 -0.1957772
sample estimates:
mean of x mean of y 
 2.361594  3.031612 
There were 50 or more warnings (use warnings() to see the first 50)

Summed Val vs. Accuracy

datac <- summarySEwithin(df, measurevar="correct", withinvars=c("multDif","difficulty"), idvar="subject")
Automatically converting the following non-factors to factors: multDif, difficulty
ggplot(datac, aes(x=difficulty, y=correct, fill=multDif)) +
    geom_bar(position=position_dodge(.9), colour="black", stat="identity") +
    geom_errorbar(position=position_dodge(.9), width=.25, aes(ymin=correct-ci, ymax=correct+ci)) +
    coord_cartesian(ylim=c(0.0,1)) +
    labs(y = "Accuracy", x = "Difficulty (net value)") +
    scale_x_discrete(labels=c("1" = "Easy (>=0.5)", "2" = "Difficult (<0.5)")) +    
    scale_y_continuous(breaks=seq(0,1,0.1)) +
    theme_bw() +
    theme(axis.title.x=element_text(size=18),
        axis.title.y = element_text(size = 18)) +
    scale_fill_brewer(palette="Pastel2") +
    guides(fill=guide_legend(title="Difference\nbetween\nMultipliers"))
setwd("/Users/djw/Dropbox/PHD/PRESENTATIONS/2017_SNE/Plots")
The working directory was changed to /Users/djw/Dropbox/PHD/PRESENTATIONS/2017_SNE/Plots inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the the working directory for notebook chunks.
ggsave("MultDif.pdf", width = 16, height = 12, units = "cm")

Summed val vs. RT

df <- S_M
There were 50 or more warnings (use warnings() to see the first 50)
#RT vs. Summed Value
ggplot() +
  geom_smooth(aes(x=summedVal, y=rt, group = factor(multNum), colour = factor(multNum)), df) +
  #geom_smooth(aes(x=summedVal, y=rt, colour = "flip"), subset(df, flip==1)) +
  coord_cartesian(xlim = c(-3, 3))  +
  #ggtitle("RT vs. Summed Val")
  #geom_point(shape=1) +    # Use hollow circles
  geom_smooth() +  # Add a loess smoothed fit curve with confidence region
  theme_minimal()+
  guides(colour=guide_legend("Multiplier \nCondition")) +
  scale_x_continuous(name="Net Value ($)", seq(-3,3,0.5), limits = c(-3,3))+
  scale_y_continuous(name = "Reaction Time (s)")

setwd("/Users/djw/Dropbox/PHD/PRESENTATIONS/2017_SNE/Plots/")
The working directory was changed to /Users/djw/Dropbox/PHD/PRESENTATIONS/2017_SNE/Plots inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the the working directory for notebook chunks.
ggsave("2ndFix.pdf", width = 18, height = 12, units = "cm")

Second Fixation vs Summed Value

df <- S_M
#RT vs. Summed Value
ggplot() +
  geom_smooth(aes(x=summedVal, y=`2_fixation`, group = factor(secondMult), colour = factor(secondMult)), df) +
  #geom_smooth(aes(x=summedVal, y=logRT, colour = "flip"), subset(total_M_clean3, flip==1)) +
  coord_cartesian(xlim = c(-3, 3))  +
  #ggtitle("Second Fixation vs Summed Value")
  #geom_point(shape=1) +    # Use hollow circles
  geom_smooth()  +# Add a loess smoothed fit curve with confidence region
  theme_minimal()+
  guides(colour=guide_legend("Multiplier \nCondition")) +
  scale_x_continuous(name="Trial Net Value ($)", seq(-3,3,0.5), limits = c(-3,3))+
  scale_y_continuous(name = "Fixation Duration (s)")

#Test for SIG
summary(lm(`2_fixation`~summedVal + factor(secondMult), df))

Call:
lm(formula = `2_fixation` ~ summedVal + factor(secondMult), data = df)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.0029 -0.3556 -0.1513  0.1609  6.7574 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)          1.034731   0.009812 105.452  < 2e-16 ***
summedVal           -0.012915   0.006777  -1.906   0.0567 .  
factor(secondMult)2  0.115010   0.019281   5.965 2.57e-09 ***
factor(secondMult)3  0.184020   0.019372   9.499  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.6114 on 6576 degrees of freedom
  (17 observations deleted due to missingness)
Multiple R-squared:  0.01601,   Adjusted R-squared:  0.01556 
F-statistic: 35.67 on 3 and 6576 DF,  p-value: < 2.2e-16

QUESTIONNAIRES

Boxplot of unfiltered data

You can see which people were not trying:

df <- S_M_raw

# Filter out extremely long rt times
df <- df[!(df$rt>10),]

boxplot(rt ~ factor(subject),
        varwidth = TRUE, xlab = "subject",
        main = "Boxplot of RT conditional on\
        subject", ylab = "RT", data = df)

Plotting mean RT vs. Earnings (unfiltered data):

KMeans to Divide into groups based on swaps/$$ (unfiltered data):

Tends to include some people who earned over $50 but never looked at the second image…

Clean data by removing people with less than 1.5 swap average and less than $0 earnings

#remove earnings below 0
total_M_clean2 <- S_M_raw[!(S_M_raw$finalEarnings<0),]
#remove flip avgs less than 1.5
total_M_clean2 <- total_M_clean2[!(total_M_clean2$flipAvg<1.5),]
length(unique(total_M_clean2$subject))

#MORE AGRESSIVE: REMOVE BELOW 75%
total_M_clean3 <- S_M_raw[!(S_M_raw$accuracy<0.75),]
length(unique(total_M_clean3$subject))

Taking out those that swapped images less than 2 times and earned less than $0 leaves 24 subjects Taking out those that had an accuracy of below 75% leaves 21 subjects

Boxplot of filtered data

A lot of variation in avg. RT and the variance of RTs. 4,7 and 23 seem to have particularly low variance.

boxplot(rt ~ factor(subject),
        varwidth = TRUE, xlab = "subject",
        main = "Boxplot of RT conditional on\
        subject", ylab = "RT", data = S_M)

Check RT distribution

Skewed right, as is typical of RT.

Histogram of

There were 41 warnings (use warnings() to see them)
is.na() applied to non-(list or vector) of type 'NULL'is.na() applied to non-(list or vector) of type 'NULL'

RTs By Subject


g = ggplot(S_M, aes(x = rt)) + geom_histogram() 

g + facet_wrap(~ subject, ncol=2)

Hist of Middle Fixations (All Subjects)

df <- S_M

#create version of dataset with only middle fixations (we use this later for drawing random middle fixations)

# make sure every trial ends with an NA val
df$`14_fixation` <- NA     

# find col Number of first fix
# Check that we are starting at column fix#1
firstFix = which(names(df) == "1_fixation")

# find the first NA val in each row
naVal <- vector(mode="numeric", length=0)
for(x in 1:length(df$Trial)){
  naVal[x] <- min(which(is.na(df[x,])))
}

# if naVal >39 then there were at least 3 fixations
midFix <- vector(mode = "numeric", length = 0)
for(x in 1:length(df$Trial)){
  if(naVal[x]>(firstFix+2)){
    for(y in (firstFix+1):(naVal[x]-2)){
      val = df[x,y]
      midFix <- c(midFix, val)
    }
  }
}

mean(midFix)
median(midFix)

S_M$finalFix
hist(midFix,
   col=rgb(1,0,0,0.5), breaks=seq(0,9,0.1), ylim=c(0,900), xlab="RT", main = "Middle Fixations")
#abline(v=median(midFix), col="blue")

legend("topright",
       c(as.expression(bquote(MidFix_Median == .(median(midFix))))),
       col = c("blue"),
       lwd = c(2, 2, 1))

Hist of Middle Fixations by Subject

load("Data/S_M_K.Rdata")
df <- S_M_K

# REMOVE First and Last Fixations
df <- df[(df$fixNum!=1 & df$revFixNum!=1),]

# SUBJECT MEANS AND SD AND FIX #
subject_means <- group_by(df, subject) %>%
  dplyr::summarize(median = median(rt, na.rm = T), mean = mean(rt, na.rm = T), sd = sd(rt, na.rm = T), count = length(rt))
subject_means

# Plot Hist
g = ggplot(df, aes(x = rt)) + 
  geom_histogram(data = transform(df, subject = NULL), fill = "blue", alpha = 0.4) +
  geom_histogram() 

g + facet_wrap(~ subject, ncol=2)

# PLot Density
# "adjust" controls the bandwidth
allFix = transform(df, subject = NULL)

g = ggplot(df, aes(x=rt)) + 
  geom_density(data = allFix, aes(alpha = 0.5, fill = "group")) +
  geom_density(aes(alpha = 0.5, fill = "subject")) +
  #geom_vline(aes(xintercept=mean(rt)), color="black", size=1) +
  scale_fill_manual(name = "Density Plot", 
                    values = c(group = "blue", subject = "red"))

appender <- function(string, prefix = "Subject: ", suffix = "  Mean: ", mean = specify_decimal(subject_means$mean[subject_means$subject == (as.numeric(string))],2)) paste0(prefix, string, suffix, mean)
              
g + facet_wrap(~ subject, ncol=2, labeller = as_labeller(appender)) +
  theme(strip.text = element_text(size = 22),
        axis.text.x = element_text(size = 18),
        axis.title.x = element_text(size = 25),
        axis.text.y = element_text(size = 18),
        axis.title.y = element_text(size = 25),
        legend.text = element_text(size = 18),
        legend.title = element_text(size = 21)) +
  ggtitle("Subject vs Group Middle Fixations (in s)")

Log RT histogram

Plot RT vs Summed Value

Plot LOG RT vs Summed Value

Plot Accuracy vs Difficulty

Hist of Accuracy vs Difficulty

SIGMOID of ACCEPT VS VALUE

d <- S_M

plot(d$summedVal, d$choice,
     main = "Choice vs. Summed Val",
     xlab="Summed Val", ylab="P (Accept)",
     xlim=c(-3, 3))

model <- glm(choice ~ summedVal, data=d, family=binomial(link = logit))
summary(model)

xv <- seq(min(d$summedVal), max(d$summedVal), 0.01)
yv <- predict(model,list(summedVal=xv), type="response")

abline(0.5,0, lty=2)
lines(xv,yv)

#Find the inflection point where there is a 50/50 probability of subject accepting.
p <- 0.5
x <- (log(p/(1-p)) - coef(model)[1]) / coef(model)[2]
x

Final Fix vs Choice

TWO DIFFICULTY CONDITIONS (Hard/Easy)

Plot Hard vs. Easy for Subjects

Plot LOG RT vs Absolute Summed Value

Plot Image Swaps vs Summed Value

Plot Image Swaps vs Absolute Value

Mean Number of Fixations

Summed Value vs. Accept/Reject Decision

Logistic regression curve

RT Correct vs Incorrect Responses

#GOOD BASE FOR PLOTTING EXAMPLE

#BAR PLOT
d <- S_M
d$correct[d$correct==1] = "Correct"
d$correct[d$correct==0] = "Incorrect"

subject_means <- group_by(d, subject, correct) %>%
  dplyr::summarize(rt = mean(rt, na.rm = T))
subject_means

#PLOT
barplot <- ggplot(subject_means, aes(x = correct, y = rt, fill=correct)) +
  stat_summary(
    geom = "bar",
    fun.y = "mean",
    col = "black",
    stat = "identity"
  ) +
  geom_point(position = position_jitter(h = 0, w = 0.2)) +
  scale_y_continuous(limits = c(0, max(d$rt, na.rm = T)),
                     expand = c(0, 0))+
  labs(y = "RT (seconds)", x = "Response")+
  theme_minimal()+
  theme(legend.position="none") +
  ggtitle("RT vs Correct Choice")

barplot 
t.test(d$rt[d$correct=="Correct"], d$rt[d$correct=="Incorrect"])

BarPlot for Choice vs RT

#BAR PLOT
d<- S_M
d$choice[d$choice==1] = "Accept"
d$choice[d$choice==0] = "Reject"

subject_means <- group_by(d, subject, choice) %>%
  dplyr::summarize(rt = mean(rt, na.rm = T))
subject_means

#PLOT
barplot <- ggplot(subject_means, aes(x = choice, y = rt, fill=choice)) +
  stat_summary(
    geom = "bar",
    fun.y = "mean",
    col = "black",
    stat = "identity"
  ) +
  geom_point(position = position_jitter(h = 0, w = 0.2)) +
  scale_y_continuous(limits = c(0, max(d$rt, na.rm = T)),
                     expand = c(0, 0))+
  labs(y = "RT (seconds)", x = "Response") +
  theme_minimal() +
  theme(legend.position="none") +
  ggtitle("RT vs Choice")
  #stat_compare_means(label.y = 8.0) +
  #stat_compare_means(ref.group = "Accept", label = "p.signif", label.y = c(7.0))

barplot 

t.test(d$rt[d$choice=="Accept"], d$rt[d$choice=="Reject"])

Deciding Factor: House/Face

#BAR PLOT
d<- S_M
# Reduce DF to Decider Trials
x<- (d$faceTotal>0 & d$houseTotal<0) | (d$faceTotal<0 & d$houseTotal>0)
d = d[x==TRUE,]
# Create Decider Column
d$decider = 0
d$decider[abs(d$faceTotal)>abs(d$houseTotal)] = "Face"
d$decider[abs(d$houseTotal)>abs(d$faceTotal)] = "House"
#remove values of zero
d = d[d$decider!=0,]

subject_means <- group_by(d, subject, decider) %>%
  dplyr::summarize(rt = mean(rt, na.rm = T))
subject_means

#PLOT
barplot <- ggplot(subject_means, aes(x = decider, y = rt, fill=decider)) +
  stat_summary(
    geom = "bar",
    fun.y = "mean",
    col = "black",
    stat = "identity"
  ) +
  geom_point(position = position_jitter(h = 0, w = 0.2)) +
  scale_y_continuous(limits = c(0, max(d$rt, na.rm = T)),
                     expand = c(0, 0))+
  labs(y = "RT (seconds)", x = "Response") +
  theme_minimal() +
  theme(legend.position="none") +
  ggtitle("RT vs Decider Stimulus")
  #stat_compare_means(label.y = 8.0) +
  #stat_compare_means(ref.group = "Accept", label = "p.signif", label.y = c(7.0))

barplot 

t.test(d$rt[d$decider=="Face"], d$rt[d$decider=="House"])

Accuracy vs Neg/Pos Summed Value

#BAR PLOT
d<- S_M
# Reduce DF to Decider Trials
d$posNeg <- 0
d$posNeg[d$summedVal>0] = "Positive"
d$posNeg[d$summedVal<0] = "Negative"
d <- d[d$summedVal!=0,] # remove values of 0

subject_means <- group_by(d, subject, posNeg) %>%
  dplyr::summarize(accuracy = mean(correct, na.rm = T))
subject_means
subject_means$meanAcc = mean(subject_means$accuracy)

#PLOT
barplot <- ggplot(subject_means, aes(x = posNeg, y = accuracy, fill=posNeg, label=accuracy)) +
  stat_summary(
    geom = "bar",
    fun.y = "mean",
    col = "black",
    stat = "identity"
  ) +
  geom_point(position = position_jitter(h = 0, w = 0.2)) +
  scale_y_continuous(limits = c(0, max(d$accuracy+0.25, na.rm = T)),
                     expand = c(0, 0))+
  labs(y = "Accuracy", x = "Summed Value") +
  theme_minimal() +
  theme(legend.position="none") +
  ggtitle("Accuracy vs Summed Value Sign")
  #stat_compare_means(label.y = 8.0) +
  #stat_compare_means(ref.group = "Accept", label = "p.signif", label.y = c(7.0))

barplot 

t.test(d$correct[d$posNeg=="Positive"], d$correct[d$posNeg=="Negative"])

RT vs Positive/Negative Summed Value

#BAR PLOT
d<- S_M
# Reduce DF to Decider Trials
d$posNeg <- 0
d$posNeg[d$summedVal>0] = "Positive"
d$posNeg[d$summedVal<0] = "Negative"
d <- d[d$summedVal!=0,] # remove values of 0

subject_means <- group_by(d, subject, posNeg) %>%
  dplyr::summarize(rt = mean(rt, na.rm = T))
subject_means

#PLOT
barplot <- ggplot(subject_means, aes(x = posNeg, y = rt, fill=posNeg)) +
  stat_summary(
    geom = "bar",
    fun.y = "mean",
    col = "black",
    stat = "identity"
  ) +
  geom_point(position = position_jitter(h = 0, w = 0.2)) +
  scale_y_continuous(limits = c(0, max(d$rt-2.5, na.rm = T)),
                     expand = c(0, 0))+
  labs(y = "RT (seconds)", x = "Summed Value") +
  theme_minimal() +
  theme(legend.position="none") +
  ggtitle("RT vs Summed Value Sign")
  #stat_compare_means(label.y = 8.0) +
  #stat_compare_means(ref.group = "Accept", label = "p.signif", label.y = c(7.0))

barplot 

t.test(d$rt[d$posNeg=="Positive"], d$rt[d$posNeg=="Negative"])

First/Middle/Last Fixation mean duration (boxPlot)

load("/Users/djw/Dropbox/PROGRAMMING/*NEURO/aDDM_Krajbich/S_M_K.Rdata")
d <- S_M_K

d$fixType <- 2
d$fixType[d$fixNum==1] <- 1
d$fixType[d$revFixNum==1] <-3

median(d$fixDur[d$fixType==1])
median(d$fixDur[d$fixType==2])
median(d$fixDur[d$fixType==3])


my_comparisons <- list( c("1", "2"), c("1", "3"), c("2", "3") )

p0 = ggboxplot(d, x = "fixType", y = "fixDur", color = "fixType", palette = "jco" )+ #outlier.shape=NA
  
  labs(y = "Fixation Time (seconds)", x = "Fixation Type") +
  theme(legend.position="none") +  
  scale_x_discrete(labels=c("1" = "First", "2" = "Middle",
                              "3" = "Last")) +
  #scale_y_continuous(limits = quantile(d$fixDur, c(0.1, 0.9))) +
  stat_compare_means(comparisons = my_comparisons)+ # Add pairwise comparisons p-value
  stat_compare_means(label.y = 13) +     # Add global p-value
  ggtitle("Fixation Durations")

p0

## How many trials with more than 2 fixatinos
d = S_M
length(d$Trial[d$swapAmount>2])/length(d$Trial)

mean(d$firstVal[d$swapAmount<2])

Summed Val vs Fixations

df <- S_M

#RT vs. Summed Value
ggplot() +
  geom_smooth(aes(x=summedVal, y=swapAmount), df) +
  #geom_smooth(aes(x=summedVal, y=logRT, colour = "flip"), subset(total_M_clean3, flip==1)) +
  coord_cartesian(xlim = c(-3, 3))  +
  ggtitle("Summed Value vs Fixations")
  #geom_point(shape=1) +    # Use hollow circles
  geom_smooth()  # Add a loess smoothed fit curve with confidence region

#Test for SIG
summary(lm(`2_fixation`~summedVal + factor(secondMult), df))
# create a dummy data frame with outliers
df = data.frame(y = c(-100, rnorm(100), 100))

# create boxplot that includes outliers
p0 = ggplot(df, aes(y = y)) + geom_boxplot(aes(x = factor(1)))

p0
# compute lower and upper whiskers
ylim1 = boxplot.stats(df$y)$stats[c(1, 5)]

# scale y limits based on ylim1
p1 = p0 + coord_cartesian(ylim = ylim1*1.05)
p1

Plot RT with/without Flip

T Test on RT difference between flip and non flip trials RT

library(tidyr)
subject_means_wide <-
  spread(subject_means,
         key = flip,
         value = rt,
         sep = "_")
subject_means_wide

#T-TEST for flip vs. non-flip trials
t.test(subject_means_wide$flip_1, subject_means_wide$flip_2, paired = TRUE)
mean(subject_means_wide$flip_2)
sd(subject_means_wide$flip_2)

Plot performance with/without Flip

There were 50 or more warnings (use warnings() to see the first 50)

Based on the plot it looks like flip trials on average do WORSE and have higher VARIANCE between subjects (in addition to taking longer)

T Test on RT difference between flip and non flip trials % Correct

subject_means_wide <-
  spread(subject_means,
         key = flip,
         value = corPct,
         sep = "_")
subject_means_wide

#T-TEST for flip vs. non-flip trials
t.test(subject_means_wide$flip_1, subject_means_wide$flip_2, paired = TRUE)
sd(subject_means_wide$flip_2)

It turns out that the difference in performance is not significant.

Plot RT vs negative/positive summed Val

Based on the plot it looks like RT is longer for negative summed values.

T Test on RT difference between pos/neg summed values

subject_means_wide <-
  spread(subject_means,
         key = posNegSum,
         value = rt,
         sep = "_")

#T-TEST for flip vs. non-flip trials
t.test(subject_means_wide$posNegSum_0, subject_means_wide$posNegSum_1, paired = TRUE)

This suggests that there is a significantly longer time spent on choices with a negative summed value.

Plot % Correct vs negative/positive summed Val

Based on the plot it looks like people do better when the summed val is positive.

T Test on RT difference between flip and non flip trials % Correct

subject_means_wide <-
  spread(subject_means,
         key = posNegSum,
         value = corPct,
         sep = "_")
subject_means_wide

#T-TEST for flip vs. non-flip trials
t.test(subject_means_wide$posNegSum_0, subject_means_wide$posNegSum_1, paired = TRUE)

The difference is significant. So people take less time but perform better when the summed value is positive.

Multipliers and Absolute Net Value

d <- S_M

# EFFECTS on Abs Val due to MULTS
subject_means <- group_by(d, subject, multNum) %>%
  dplyr::summarize(absNet = mean(absSummedVal, na.rm = T), rt = mean(rt, na.rm = T))
subject_means

# Mean by Mult
mean(subject_means$absNet[subject_means$multNum == 0])
mean(subject_means$absNet[subject_means$multNum == 1])
mean(subject_means$absNet[subject_means$multNum == 2])

# SD by Mult
sd(subject_means$absNet[subject_means$multNum == 0])
sd(subject_means$absNet[subject_means$multNum == 1])
sd(subject_means$absNet[subject_means$multNum == 2])

# 0 1
t.test(subject_means$absNet[subject_means$multNum == 0],
                            subject_means$absNet[subject_means$multNum == 1], paired = TRUE)
# 1 2
t.test(subject_means$absNet[subject_means$multNum == 1],
                            subject_means$absNet[subject_means$multNum == 2], paired = TRUE)
# 0 2
t.test(subject_means$absNet[subject_means$multNum == 0],
       subject_means$absNet[subject_means$multNum == 2], paired = TRUE)

RT distributions for different multNums

d = S_M

med.fac = ddply(d, .(multNum), function(.d)
data.frame(x=median(.d$rt)))

# HISTOGRAM VERSION
p <- ggplot(data = d, aes(x = rt, fill=multNum)) + 
  geom_histogram() +
  labs(title="RT Distribution vs. Number of Multipliers", x = "RT (seconds)", y ="Count") +
  geom_vline(data=med.fac, aes(xintercept=x)) +
  theme_minimal() +
  theme(legend.position="none")
p + facet_wrap(~multNum)

# BOXPLOT VERSION

# create medians to insert as text
x <- d
x$multNum = d$multNum+1
p_meds <- ddply(x, .(multNum), summarise, med = median(rt))
p_meds$med = round(p_meds$med, digits = 2)  # round to two decimal values

# List of conditions to compare
my_comparisons <- list( c("0", "1"), c("0", "2"), c("1", "2") )

p0 = ggboxplot(d, x = "multNum", y = "rt", color = "multNum", palette = "jco" )+ #outlier.shape=NA
  
  labs(y = "Total RT (seconds)", x = "Number of Multipliers") +
  theme(legend.position="none") +  
  scale_x_discrete(labels=c("0" = "None", "1" = "One",
                              "2" = "Two")) +
  #scale_y_continuous(limits = quantile(d$fixDur, c(0.1, 0.9))) +
  stat_compare_means(comparisons = my_comparisons)+ # Add pairwise comparisons p-value
  stat_compare_means(label.y = 13) +     # Add global p-value
  geom_text(data = p_meds, aes(x = multNum, y = med, label = med), 
              size = 3, vjust = -1.5) +
  ggtitle("RT Distribution vs. Number of Multipliers")

p0

RT by Mult for “Difficult” trials

# create medians to insert as text
d<- S_M
d <- d[d$absSummedVal<0.5, ] # limit to absolute summed values below 0.50
x <- d
x$multNum = d$multNum+1
p_meds <- ddply(x, .(multNum), summarise, med = median(rt))
p_meds$med = round(p_meds$med, digits = 2)  # round to two decimal values

# List of conditions to compare
my_comparisons <- list( c("0", "1"), c("0", "2"), c("1", "2") )

p0 = ggboxplot(d, x = "multNum", y = "rt", color = "multNum", palette = "jco" )+ #outlier.shape=NA
  
  labs(y = "Total RT (seconds)", x = "Number of Multipliers") +
  theme(legend.position="none") +  
  scale_x_discrete(labels=c("0" = "None", "1" = "One",
                              "2" = "Two")) +
  #scale_y_continuous(limits = quantile(d$fixDur, c(0.1, 0.9))) +
  stat_compare_means(comparisons = my_comparisons)+ # Add pairwise comparisons p-value
  stat_compare_means(label.y = 13) +     # Add global p-value
  geom_text(data = p_meds, aes(x = multNum, y = med, label = med), 
              size = 3, vjust = -1.5) +
  ggtitle("RT Distribution vs. Number of Multipliers: Absolute Summed Value < $0.50")

p0

RT by Mult for “Easy” trials

# create medians to insert as text
d<- S_M
d <- d[d$absSummedVal>1.0, ] # limit to absolute summed values below 0.50
x <- d
x$multNum = d$multNum+1
p_meds <- ddply(x, .(multNum), summarise, med = median(rt))
p_meds$med = round(p_meds$med, digits = 2)  # round to two decimal values

# List of conditions to compare
my_comparisons <- list( c("0", "1"), c("0", "2"), c("1", "2") )

p0 = ggboxplot(d, x = "multNum", y = "rt", color = "multNum", palette = "jco" )+ #outlier.shape=NA
  
  labs(y = "Total RT (seconds)", x = "Number of Multipliers") +
  theme(legend.position="none") +  
  scale_x_discrete(labels=c("0" = "None", "1" = "One",
                              "2" = "Two")) +
  #scale_y_continuous(limits = quantile(d$fixDur, c(0.1, 0.9))) +
  stat_compare_means(comparisons = my_comparisons)+ # Add pairwise comparisons p-value
  stat_compare_means(label.y = 13) +     # Add global p-value
  geom_text(data = p_meds, aes(x = multNum, y = med, label = med), 
              size = 3, vjust = -1.5) +
  ggtitle("RT Distribution vs. Number of Multipliers: Absolute Summed Value > $1.00")

p0

d<- S_M
d <- d[d$absSummedVal<0.25, ] # limit to absolute summed values below 0.50
subject_means <- group_by(d, multNum) %>%
  dplyr::summarize(median = mean(correct, na.rm = T))
subject_means

What is the mean abs value of combos with 0/1/2 mults?

Highest for 1 multiplier

d <- S_M

d0 <- d[d$multNum == 0, ]
d1 <- d[d$multNum == 1, ]
d2 <- d[d$multNum == 2, ]

mean(d0$absSummedVal)
mean(d1$absSummedVal)
mean(d2$absSummedVal)

PSYCHOMETRICS

Study 1/Study 2, RT and Accuracy

load("Data/NS_M.Rdata")
There were 50 or more warnings (use warnings() to see the first 50)
d1 <- NS_M
d2 <- S_M
# Create ID for each DF
d1$study <- "Standard Mult."
d2$study <- "Swap Mult."
# Need to uniquely number Subjects
d2$subject <- d2$subject + 100
# Concat DFs
common_cols <- intersect(colnames(d1), colnames(d2))
df = rbind(
  d1[, common_cols], 
  d2[, common_cols]
)
# GROUPBY
subject_means <- group_by(df, subject, study) %>%
  dplyr::summarize(accuracy = mean(correct, na.rm = T), rt = mean(rt, na.rm = T), meanSwap = mean(swapAmount, na.rm = T))
Error in summarise_impl(.data, dots) : 
  Evaluation error: object 'swapAmount' not found.

Create Binned Values to test against Accuracy and RT

setwd("/Users/djw/Dropbox/PHD/PRESENTATIONS/2017_SNE/Plots")
The working directory was changed to /Users/djw/Dropbox/PHD/PRESENTATIONS/2017_SNE/Plots inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the the working directory for notebook chunks.
ggsave("Prob.png", width = 19, height = 12, units = "cm")

Same as above but for abs Val for RT and Fixation

  
setwd("/Users/djw/Dropbox/PHD/PRESENTATIONS/2017_SNE/Plots")
The working directory was changed to /Users/djw/Dropbox/PHD/PRESENTATIONS/2017_SNE/Plots inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the the working directory for notebook chunks.
ggsave("RT.png", width = 19, height = 12, units = "cm")

FUNCTIONS for SUMMARY STATS

From: http://www.cookbook-r.com/Graphs/Plotting_means_and_error_bars_(ggplot2)/#Helper%20functions

## Norms the data within specified groups in a data frame; it normalizes each
## subject (identified by idvar) so that they have the same mean, within each group
## specified by betweenvars.
##   data: a data frame.
##   idvar: the name of a column that identifies each subject (or matched subjects)
##   measurevar: the name of a column that contains the variable to be summariezed
##   betweenvars: a vector containing names of columns that are between-subjects variables
##   na.rm: a boolean that indicates whether to ignore NA's
normDataWithin <- function(data=NULL, idvar, measurevar, betweenvars=NULL,
                           na.rm=FALSE, .drop=TRUE) {
    library(plyr)
    # Measure var on left, idvar + between vars on right of formula.
    data.subjMean <- ddply(data, c(idvar, betweenvars), .drop=.drop,
     .fun = function(xx, col, na.rm) {
        c(subjMean = mean(xx[,col], na.rm=na.rm))
      },
      measurevar,
      na.rm
    )
    # Put the subject means with original data
    data <- merge(data, data.subjMean)
    # Get the normalized data in a new column
    measureNormedVar <- paste(measurevar, "_norm", sep="")
    data[,measureNormedVar] <- data[,measurevar] - data[,"subjMean"] +
                               mean(data[,measurevar], na.rm=na.rm)
    # Remove this subject mean column
    data$subjMean <- NULL
    return(data)
}
## Summarizes data, handling within-subjects variables by removing inter-subject variability.
## It will still work if there are no within-S variables.
## Gives count, un-normed mean, normed mean (with same between-group mean),
##   standard deviation, standard error of the mean, and confidence interval.
## If there are within-subject variables, calculate adjusted values using method from Morey (2008).
##   data: a data frame.
##   measurevar: the name of a column that contains the variable to be summariezed
##   betweenvars: a vector containing names of columns that are between-subjects variables
##   withinvars: a vector containing names of columns that are within-subjects variables
##   idvar: the name of a column that identifies each subject (or matched subjects)
##   na.rm: a boolean that indicates whether to ignore NA's
##   conf.interval: the percent range of the confidence interval (default is 95%)
summarySEwithin <- function(data=NULL, measurevar, betweenvars=NULL, withinvars=NULL,
                            idvar=NULL, na.rm=FALSE, conf.interval=.95, .drop=TRUE) {
  # Ensure that the betweenvars and withinvars are factors
  factorvars <- vapply(data[, c(betweenvars, withinvars), drop=FALSE],
    FUN=is.factor, FUN.VALUE=logical(1))
  if (!all(factorvars)) {
    nonfactorvars <- names(factorvars)[!factorvars]
    message("Automatically converting the following non-factors to factors: ",
            paste(nonfactorvars, collapse = ", "))
    data[nonfactorvars] <- lapply(data[nonfactorvars], factor)
  }
  # Get the means from the un-normed data
  datac <- summarySE(data, measurevar, groupvars=c(betweenvars, withinvars),
                     na.rm=na.rm, conf.interval=conf.interval, .drop=.drop)
  # Drop all the unused columns (these will be calculated with normed data)
  datac$sd <- NULL
  datac$se <- NULL
  datac$ci <- NULL
  # Norm each subject's data
  ndata <- normDataWithin(data, idvar, measurevar, betweenvars, na.rm, .drop=.drop)
  # This is the name of the new column
  measurevar_n <- paste(measurevar, "_norm", sep="")
  # Collapse the normed data - now we can treat between and within vars the same
  ndatac <- summarySE(ndata, measurevar_n, groupvars=c(betweenvars, withinvars),
                      na.rm=na.rm, conf.interval=conf.interval, .drop=.drop)
  # Apply correction from Morey (2008) to the standard error and confidence interval
  #  Get the product of the number of conditions of within-S variables
  nWithinGroups    <- prod(vapply(ndatac[,withinvars, drop=FALSE], FUN=nlevels,
                           FUN.VALUE=numeric(1)))
  correctionFactor <- sqrt( nWithinGroups / (nWithinGroups-1) )
  # Apply the correction factor
  ndatac$sd <- ndatac$sd * correctionFactor
  ndatac$se <- ndatac$se * correctionFactor
  ndatac$ci <- ndatac$ci * correctionFactor
  # Combine the un-normed means with the normed results
  merge(datac, ndatac)
}
## Gives count, mean, standard deviation, standard error of the mean, and confidence interval (default 95%).
##   data: a data frame.
##   measurevar: the name of a column that contains the variable to be summariezed
##   groupvars: a vector containing names of columns that contain grouping variables
##   na.rm: a boolean that indicates whether to ignore NA's
##   conf.interval: the percent range of the confidence interval (default is 95%)
summarySE <- function(data=NULL, measurevar, groupvars=NULL, na.rm=FALSE,
                      conf.interval=.95, .drop=TRUE) {
    library(plyr)
    # New version of length which can handle NA's: if na.rm==T, don't count them
    length2 <- function (x, na.rm=FALSE) {
        if (na.rm) sum(!is.na(x))
        else       length(x)
    }
    # This does the summary. For each group's data frame, return a vector with
    # N, mean, and sd
    datac <- ddply(data, groupvars, .drop=.drop,
      .fun = function(xx, col) {
        c(N    = length2(xx[[col]], na.rm=na.rm),
          mean = mean   (xx[[col]], na.rm=na.rm),
          sd   = sd     (xx[[col]], na.rm=na.rm)
        )
      },
      measurevar
    )
    # Rename the "mean" column    
    datac <- rename(datac, c("mean" = measurevar))
    datac$se <- datac$sd / sqrt(datac$N)  # Calculate standard error of the mean
    # Confidence interval multiplier for standard error
    # Calculate t-statistic for confidence interval: 
    # e.g., if conf.interval is .95, use .975 (above/below), and use df=N-1
    ciMult <- qt(conf.interval/2 + .5, datac$N-1)
    datac$ci <- datac$se * ciMult
    return(datac)
}

Difficult, Very Difficult, Easy, Overall RT and Accuracy by MultNum

d <- S_M
There were 41 warnings (use warnings() to see them)
# Remove abs summed values >1.00 and <0.50
d <- d[(d$absSummedVal<=0.50) | (d$absSummedVal>=1.00),]
# Create Difficulty Level and Factor it
d$difficulty = 1  # easy level
d$difficulty[d$absSummedVal<0.5] = 2 # Difficult level
d$difficulty[d$absSummedVal<0.25] = 3 # V.Difficult level
# Factor conditions
d$multNum <- factor(d$multNum)
d$difficulty <- factor(d$difficulty)
# FOR T-TESTS
subject_means <- group_by(d, subject, difficulty, multNum) %>%
  dplyr::summarize(accuracy = mean(correct), rt = mean(rt))
subject_means
# Paired TTest
# Accuracy
# Easy vs Hard
mean(subject_means$accuracy[subject_means$difficulty == 1])
[1] 0.9519747
mean(subject_means$accuracy[subject_means$difficulty == 3])
[1] 0.6752014
sd(subject_means$accuracy[subject_means$difficulty == 1])
[1] 0.06967094
sd(subject_means$accuracy[subject_means$difficulty == 3])
[1] 0.1424739
       
t.test(subject_means$accuracy[subject_means$difficulty == 1],
       subject_means$accuracy[subject_means$difficulty == 3], paired = TRUE)

    Paired t-test

data:  subject_means$accuracy[subject_means$difficulty == 1] and subject_means$accuracy[subject_means$difficulty == 3]
t = 14.77, df = 68, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.2393794 0.3141673
sample estimates:
mean of the differences 
              0.2767733 
# Easy, 0 Mult/1 Mult
mean(subject_means$accuracy[subject_means$difficulty == 1 & subject_means$multNum == 0])
[1] 0.9877854
mean(subject_means$accuracy[subject_means$difficulty == 1 & subject_means$multNum == 1])
[1] 0.9482313
sd(subject_means$accuracy[subject_means$difficulty == 1 & subject_means$multNum == 0])
[1] 0.03119811
sd(subject_means$accuracy[subject_means$difficulty == 1 & subject_means$multNum == 1])
[1] 0.05554537
t.test(subject_means$accuracy[subject_means$difficulty == 1 & subject_means$multNum == 0],
       subject_means$accuracy[subject_means$difficulty == 1 & subject_means$multNum == 1], paired = TRUE)

    Paired t-test

data:  subject_means$accuracy[subject_means$difficulty == 1 & subject_means$multNum ==  and subject_means$accuracy[subject_means$difficulty == 1 & subject_means$multNum ==     0] and     1]
t = 5.1382, df = 22, p-value = 3.772e-05
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.02358934 0.05551889
sample estimates:
mean of the differences 
             0.03955411 
# Hard, 0 Mult/1 Mult
mean(subject_means$accuracy[subject_means$difficulty == 3 & subject_means$multNum == 0])
[1] 0.585889
mean(subject_means$accuracy[subject_means$difficulty == 3 & subject_means$multNum == 1])
[1] 0.7318523
sd(subject_means$accuracy[subject_means$difficulty == 3 & subject_means$multNum == 0])
[1] 0.1247233
sd(subject_means$accuracy[subject_means$difficulty == 3 & subject_means$multNum == 1])
[1] 0.1278067
t.test(subject_means$accuracy[subject_means$difficulty == 3 & subject_means$multNum == 0],
       subject_means$accuracy[subject_means$difficulty == 3 & subject_means$multNum == 1], paired = TRUE)

    Paired t-test

data:  subject_means$accuracy[subject_means$difficulty == 3 & subject_means$multNum ==  and subject_means$accuracy[subject_means$difficulty == 3 & subject_means$multNum ==     0] and     1]
t = -4.4311, df = 22, p-value = 0.0002105
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.21427733 -0.07764923
sample estimates:
mean of the differences 
             -0.1459633 
# Paired TTest
# RT
# Easy vs Hard
mean(subject_means$rt[subject_means$difficulty == 1])
[1] 2.714638
mean(subject_means$rt[subject_means$difficulty == 3])
[1] 3.428044
sd(subject_means$rt[subject_means$difficulty == 1])
[1] 0.9481159
sd(subject_means$rt[subject_means$difficulty == 3])
[1] 1.115059
       
t.test(subject_means$rt[subject_means$difficulty == 1],
       subject_means$rt[subject_means$difficulty == 3], paired = TRUE)

    Paired t-test

data:  subject_means$rt[subject_means$difficulty == 1] and subject_means$rt[subject_means$difficulty == 3]
t = -10.001, df = 68, p-value = 5.434e-15
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.8557461 -0.5710664
sample estimates:
mean of the differences 
             -0.7134063 
# Easy, 0 Mult/1 Mult
mean(subject_means$rt[subject_means$difficulty == 1 & subject_means$multNum == 0])
[1] 2.503676
mean(subject_means$rt[subject_means$difficulty == 1 & subject_means$multNum == 1])
[1] 2.666323
sd(subject_means$rt[subject_means$difficulty == 1 & subject_means$multNum == 0])
[1] 0.857097
sd(subject_means$rt[subject_means$difficulty == 1 & subject_means$multNum == 1])
[1] 0.8832649
t.test(subject_means$rt[subject_means$difficulty == 1 & subject_means$multNum == 0],
       subject_means$rt[subject_means$difficulty == 1 & subject_means$multNum == 1], paired = TRUE)

    Paired t-test

data:  subject_means$rt[subject_means$difficulty == 1 & subject_means$multNum ==  and subject_means$rt[subject_means$difficulty == 1 & subject_means$multNum ==     0] and     1]
t = -3.2763, df = 22, p-value = 0.003451
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.2656007 -0.0596928
sample estimates:
mean of the differences 
             -0.1626467 
# Hard, 0 Mult/1 Mult
mean(subject_means$rt[subject_means$difficulty == 3 & subject_means$multNum == 0])
[1] 3.485174
mean(subject_means$rt[subject_means$difficulty == 3 & subject_means$multNum == 1])
[1] 3.216965
sd(subject_means$rt[subject_means$difficulty == 3 & subject_means$multNum == 0])
[1] 1.173273
sd(subject_means$rt[subject_means$difficulty == 3 & subject_means$multNum == 1])
[1] 1.183658
t.test(subject_means$rt[subject_means$difficulty == 3 & subject_means$multNum == 0],
       subject_means$rt[subject_means$difficulty == 3 & subject_means$multNum == 1], paired = TRUE)

    Paired t-test

data:  subject_means$rt[subject_means$difficulty == 3 & subject_means$multNum ==  and subject_means$rt[subject_means$difficulty == 3 & subject_means$multNum ==     0] and     1]
t = 2.3206, df = 22, p-value = 0.02997
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.0285203 0.5078978
sample estimates:
mean of the differences 
              0.2682091 
#------------#
# PLOT       #
#------------#
# For RT
# Stats Summary
datac <- summarySEwithin(d, measurevar="rt", withinvars=c("multNum","difficulty"), idvar="subject")
ggplot(datac, aes(x=difficulty, y=rt, fill=multNum)) +
    geom_bar(position=position_dodge(.9), colour="black", stat="identity") +
    geom_errorbar(position=position_dodge(.9), width=.25, aes(ymin=rt-ci, ymax=rt+ci)) +
    coord_cartesian(ylim=c(2,4)) +
    labs(y = "Total RT (s)", x = "Difficulty (net value)") +
    scale_x_discrete(labels=c("1" = "Easy (>1)", "2" = "Difficult (0.5<0.25)",
                              "3" = "Very Difficult (<0.25)")) +
    scale_y_continuous(breaks=seq(2,4,0.2)) +
    theme_bw() +
    scale_fill_discrete(name="Number of\nMultipliers") 

    #ggtitle("RT vs. Difficulty + Number of Multipliers")  
# For Accuracy
# Stats Summary
datac <- summarySEwithin(d, measurevar="correct", withinvars=c("multNum","difficulty"), idvar="subject")
ggplot(datac, aes(x=difficulty, y=correct, fill=multNum)) +
    geom_bar(position=position_dodge(.9), colour="black", stat="identity") +
    geom_errorbar(position=position_dodge(.9), width=.25, aes(ymin=correct-ci, ymax=correct+ci)) +
    coord_cartesian(ylim=c(0.5,1)) +
    labs(y = "Accuracy", x = "Difficulty (net value)") +
    scale_x_discrete(labels=c("1" = "Easy (>1)", "2" = "Difficult (0.5<0.25)",
                              "3" = "Very Difficult (<0.25)")) +    
    scale_y_continuous(breaks=seq(0,1,0.1)) +
    theme_bw() +
    scale_fill_discrete(name="Number of\nMultipliers") 

    #ggtitle("Accuracy vs. Difficulty + Number of Multipliers")  

ANOVA

ANOVA on difference between multiplier and non multiplier trials RT

Based on this, there is no significant effect (as expressed through RT) in having one multiplier, however there is for having two.

Based on this, there is no significant effect (as expressed through RT) in having one multiplier, however there is for having two.

FIXATION DURATION

load("Data/S_M_K.Rdata")
d <- S_M_K

# Factor conditions
d$subject <- factor(d$subject)

# FOR T-TESTS
subject_means <- group_by(d, subject) %>%
  dplyr::summarize(firstFix = mean(fixDur[fixNum == 1]),
                   middleFix = mean(fixDur[fixNum > 1 & revFixNum > 1]),
                   finalFix = mean(fixDur[revFixNum == 1]))
subject_means

# Paired TTest
# RT
mean(subject_means$firstFix)
mean(subject_means$middleFix)
mean(subject_means$finalFix)
sd(subject_means$firstFix)
sd(subject_means$middleFix)
sd(subject_means$finalFix)

t.test(subject_means$middleFix,
       subject_means$finalFix, paired = TRUE)

Linear Models for Dependent (Fixed) Effects (not taking random effects into account)

First Fixation Duration vs. First Image Total Value

First Fixation Duration vs. First Mult

APRIL 24: NEW ANALYSES

Mixed Models

FOR STARTERS: Does summed value affect RT (using log RT)?

Perhaps unsurprisingly based on what we plotted before, summed value has a highly significant effect on reaction time (controlling for random effects of subjects).

Summed Value as the individual TOTAL values (the value x multiplier) of the FACE and HOUSE

Based on this there is a significant difference between mean RT and rt.model2 as well as between rt.model2 and rt.model1

What about interaction between faceTotal and houseTotal?

So there is a significant interaction bewteen the total house value and the total face value (as expected).

And then what if we look at the components (value * multiplier) of the Total Face and Total House Value?

Again, based on the anova analysis there seems to be significance in the interactions between the values and the multipliers.

—————————————–

RT PLOTS

Plot RT random effects of subjects

Plot RT with multiple lines (average of each subjects line)

  • multiplier trials
  • flip trials
  • non flip trials
  • non mult trials

Note that with the flip trials the summed values ranged from -0.6 to 0.6.

Plot Accuracy (% correct) with multiple lines (average of each subjects line)

  • multiplier trials
  • flip trials
  • non flip trials
  • non mult trials

Same Plot but just for “Difficult” choices

RT for difficult choices by multNum

CHOICE CURVE

% acceptance (sinusoid) -sinusoid for non mult/mult/flip

Value of first item vs. First item fixation time

  • no mult
  • 2x mult
  • 3x mult

Value of second item vs. Second item fixation time

  • no mult
  • 2x mult
  • 3x mult

Summed value vs second item fixation time

Number of swaps

  • based on summed value
  • based on ambiguity of individual stimuli (ie. closer to zero) -stimulus left has ambiguity X, stimulus right has ambiguity Y, summed value has ambiguity Z -how much does individual ambiguity vs combined ambiguity affect RT/swaps

SALIENCY TEST: Mean Fixation House v. Face

People looked at HOUSES longer. More salient? Or more ambiguous?

FINAL FIXATION: Tied to Value?

Are people taking longer for flip trials after accounting for fact that flip trials ALWAYS have multipliers (and non-flip trials don’t)

This is not currently working

Questionnaire Data

Plotting GPA vs. Earnings (unfiltered data):

Stroop Data

ANOVA for significance

#reformat Data Frame
found = which(rt_by_condition!=-999,arr.ind=T)
rtANOVA = data.frame(cbind(found,rt_by_condition[found]))
names(rtANOVA) = c('subj','cond','rt')

rtANOVA$subj = factor(rtANOVA$subj)
rtANOVA$cond = factor(rtANOVA$cond)

myaov = aov(rtANOVA$rt~rtANOVA$cond+Error(rtANOVA$subj))
summary(myaov)

T-Test

#reformat Data Frame
t.test(rt_by_condition$congruent,rt_by_condition$incongruent,paired=T,mu=0,alternative="two.sided",var.equal=T)

Based on Anova/TTest seems like there is a significant difference.

#Select dataframe to use
d <- Stroop.df.clean

#mean RT and Final earnings by subject
Stroop.performance <- group_by(d, subject) %>%
  dplyr::summarize(rt = mean(Response.rt, na.rm = T), accuracy = mean(Response.corr, na.rm = T))
Stroop.performance$performance = Stroop.performance$rt * 1/Stroop.performance$accuracy
#invert so bigger nunbers are better
Stroop.performance$performance = 1/Stroop.performance$performance

Stroop Performance vs. Task Performance

vs Earnings

vs Accuracy

vs RT

EFFECT SIZE

Cohen’s D

#Select dataframe to use
d <- total_M_clean3

#mean RT and Final earnings by subject
rt_mults <- group_by(d, subject) %>%
  dplyr::summarize(mult_0 = mean(RT[multNum==0]), mult_1 = mean(RT[multNum==1], na.rm = T), mult_2 = mean(RT[multNum==2], na.rm=T))
rt_mults

library(lsr)
cohensD(rt_mults$mult_0, rt_mults$mult_1)
cohensD(rt_mults$mult_0, rt_mults$mult_2)

MEANS

List of Mean RTs for Mults

#Select dataframe to use
d <- total_M_clean3

#mean RT depending on multiplier combination
for(i in 1:3){
  for(j in 1:3){
    m <- mean(d$RT[d$mult1House==i & d$mult2Face==j])
    cat(sprintf("House Mult = %s and Face Mult = %s\n", i, j))
    cat(sprintf("Mean: %f\n\n", m))
  }
}

MORE MIXED EFFECTS STUFF

Simulate RTs based on data

Abs Val vs. RT

Subject Level

APA Format Plotting

apatheme=theme_bw()+
  theme(panel.grid.major=element_blank(),
        panel.grid.minor=element_blank(),
        panel.border=element_blank(),
        axis.line=element_line(),
        text=element_text(family='Times'))

LME

with help from Liz

ggplot(fitDf, aes(`Fixed Effects`, z, fill=`Fixed Effects`)) + 
  geom_bar(stat = "identity", width = 0.5) + 
  geom_errorbar(aes(ymin=z-se, ymax=z+se), width=0.4) +
  geom_text(aes(label=star), colour="black", vjust=0, size=6) +
  scale_x_discrete(limits = positions) +
  theme_minimal() +
  theme(axis.title.x=element_text(size=14),
      axis.title.y = element_text(size = 14))+
  theme(legend.position="none")
setwd("/Users/djw/Dropbox/PHD/PRESENTATIONS/2017_SNE/Plots/")
The working directory was changed to /Users/djw/Dropbox/PHD/PRESENTATIONS/2017_SNE/Plots inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the the working directory for notebook chunks.
ggsave("fixedEffects.pdf", width = 20, height = 12, units = "cm")

Test to see if RT for incorrect is longer than RT for correct?

LOOKING AT QUESTIONNAIRE DATA

Note that this is the for the “cleaned” subjects. Running this with all of the subjects gives a significant effect to Self-Control.

MULT DIF and MODELS…

TEST TO SEE IF INTERACTION IS SIGNIFICANT

F-test is used to compare the residual sum of squares of both the models

drop1(model.1i, test = “F”) *doesn’t seem to work with lme (example is with lm)

MODEL VALIDATION

  1. residuals versus fitted values to verify homogeneity

  2. a QQ-plot or histogram of the residuals for normality

  3. residuals versus each explanatory variable to check independence

**Instead of a visual inspection, it is also possible to apply a test for homogeneity. Sokal and Rohlf (1995) describe three such tests, namely 1. the Barlett’s test for homogeneity *sensitive to non-normality! 2. Hartley’s Fmax test and the log-anova 3. Scheffe ́-Box test

help(t.test)
LS0tCnRpdGxlOiAiU3dhcF9NdWx0IEFuYWx5c2lzIgphdXRob3I6ICJEYW5pZWwgSiBXaWxzb24iCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClRoaXMgaXMgYW4gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuIAoKYGBge3IgY2xlYW51cH0KIyByZW1vdmVzIGFsbCB2YXJpYWJsZXMgYnV0IE5PVCBmdW5jdGlvbnMKcm0obGlzdCA9IHNldGRpZmYobHMoKSwgbHNmLnN0cigpKSkKYGBgCgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9VFJVRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSkKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkobG1lNCkKbGlicmFyeSh0aWR5cikKbGlicmFyeShtZXJUb29scykgCmxpYnJhcnkobHNyKQpsaWJyYXJ5KHJlc2hhcGUyKQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShwbHlyKQpsaWJyYXJ5KEhtaXNjKSAjIGN1dDIKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmBgYAoKYGBge3J9CnNwZWNpZnlfZGVjaW1hbCA8LSBmdW5jdGlvbih4LCBrKSB0cmltd3MoZm9ybWF0KHJvdW5kKHgsIGspLCBuc21hbGw9aykpCmBgYAoKIyBJbWFnZSBTd2FwIFZlcnNpb24KCiMjI0FuYWx5c2lzIG9mIHRoZSAqTVVMVElQTElFUiogdHJpYWxzIGZpcnN0CmBzdGlsbCBuZWVkIHRvIHdvcmsgb3V0IGhvdyB0byBzZWxlY3Qgc3ViamVjdCBpZiB0aGUgTk0gdHJpYWxzIGJhc2VkIG9uIHRoZWlyIHBlcmZvcm1hbmNlIGluIHRoZSBtdWx0aXBsaWVyIHRyaWFsc2AKCiMjRGF0YWZyYW1lIGhlYWRlcgoKYGBge3IgZGF0YWZyYW1lfQojIHNldCBXRApzZXR3ZCgifi9Ecm9wYm94L1BST0dSQU1NSU5HL19ORVVSTy8yMDE3X01BREUvQW5hbHlzaXMiKQoKbG9hZCgiRGF0YS9TX00uUmRhdGEiKQpsb2FkKCJEYXRhL1NfTV9yYXcuUmRhdGEiKQoKbG9hZCgiRGF0YS9OU19NLlJkYXRhIikKCmxvYWQoIkRhdGEvU19OTS5SZGF0YSIpCmxvYWQoIkRhdGEvU19OTV9yYXcuUmRhdGEiKQpoZWFkKFNfTV9yYXcpCmBgYApgYGB7cn0KbWVhbihTX05NJHJ0KQptZWFuKFNfTk0kYWNjdXJhY3kpCm1lYW4oU19OTSRzd2FwQW1vdW50KQoKbWVhbihTX00kcnQpCm1lYW4oU19NJGFjY3VyYWN5KQpzZChTX00kYWNjdXJhY3kpCm1lYW4oU19NJHN3YXBBbW91bnQpCgoKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShTX01fcmF3LCBzdWJqZWN0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHN3YXBzID0gbWVhbihzd2FwQW1vdW50LCBuYS5ybSA9VCkpCnBsb3Qoc3ViamVjdF9tZWFucykKCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoU19NX3Jhdywgc3ViamVjdCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShydCA9IG1lYW4ocnQsIG5hLnJtID0gVCksIGZpbmFsRWFybmluZ3MgPSBtZWFuKGZpbmFsRWFybmluZ3MsIG5hLnJtID0gVCkpCmBgYAojIyBUYWJsZSBvZiBzdWJqZWN0IGNvdW50LCBtZWFuLCBtZWRpYW4sIFNELCByYW5nZSwgc2tldywga3VydG9zaXMKIyMjIEV4cGVyaW1lbnQgMS8yCiMjIyMgQWNjdXJhY3ksIHJ0CiMjIyMjIFVuY2xlYW5lZC9DbGVhbmVkCgpgYGB7cn0KbG9hZCgiRGF0YS9tYWRlX2Rlc2NyaXBpdmVfc3RhdHMuUmRhdGEiKQpgYGAKCiMjIEFkZCBhbGwgREZzIChjbGVhbmVkKSwgbWFyayBieSBjb25kaXRpb24KIyMjIFBsb3QgYm94cGxvdHMgb2YgcnQgYW5kIGFjY3VyYWN5CgpgYGB7cn0KbG9hZCgiRGF0YS9OU19OTS5SZGF0YSIpCmxvYWQoIkRhdGEvTlNfTS5SZGF0YSIpCmxvYWQoIkRhdGEvU19OTS5SZGF0YSIpCmxvYWQoIkRhdGEvU19NLlJkYXRhIikKCk5TX05NJHR5cGUgPSAiTm9Td2FwX05vTXVsdCIKTlNfTSR0eXBlID0gIk5vU3dhcF9NdWx0IgpTX05NJHR5cGUgPSAiU3dhcF9Ob011bHQiClNfTSR0eXBlID0gIlN3YXBfTXVsdCIKCiMgSm9pbiBhbGwgREZzCmNvbW1vbiA8LSBpbnRlcnNlY3QobmFtZXMoTlNfTk0pLCBuYW1lcyhOU19NKSkKZGYgPSByYmluZChOU19OTVssY29tbW9uXSwgTlNfTVssY29tbW9uXSkKCmNvbW1vbiA8LSBpbnRlcnNlY3QobmFtZXMoU19OTSksIG5hbWVzKFNfTSkpCmRmMiA9IHJiaW5kKFNfTk1bLGNvbW1vbl0sIFNfTVssY29tbW9uXSkKCmNvbW1vbiA8LSBpbnRlcnNlY3QobmFtZXMoZGYpLCBuYW1lcyhkZjIpKQpkZl9mdWxsID0gcmJpbmQoZGZbLGNvbW1vbl0sIGRmMlssY29tbW9uXSkKCiMgQm94cGxvdCBSVApib3hwbG90KHJ0IH4gZmFjdG9yKHR5cGUpLAogICAgICAgIHZhcndpZHRoID0gVFJVRSwgeGxhYiA9ICJUcmlhbCBUeXBlIiwKICAgICAgICBtYWluID0gIlJUIGJ5IFRyaWFsIFR5cGUiLCB5bGFiID0gIlJUIGluIHMiLCBkYXRhID0gZGZfZnVsbCkKCiMgQmFycGxvdCBvZiBBY2N1cmFjeQojRmlyc3QgZ2V0IG1lYW5zIGZvciBlYWNoIHRyaWFsIGNvbmRpdGlvbiAodHlwZSkgYnkgU3ViamVjdApkIDwtIGRmX2Z1bGwKCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZCwgdHlwZSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShhY2N1cmFjeSA9IG1lYW4oY29ycmVjdCwgbmEucm0gPSBUKSkKCnN1YmplY3RfbWVhbnMkYWNjdXJhY3kgPSByb3VuZChzdWJqZWN0X21lYW5zJGFjY3VyYWN5LCAzKQoKI1BMT1QKbG93ZXI9YygwLjc4Nzk5MCwgMC43ODc2OTQsIDAuNzk4NDA0LCAwLjc1OTAwNSkgCnVwcGVyPWMoMC44Nzc2MzgsIDAuODY3Njk5LCAwLjg4MDAyOSwgMC44OTM3MjkpCgpiYXJwbG90IDwtIGdncGxvdChzdWJqZWN0X21lYW5zLCBhZXMoeCA9IHR5cGUsIHkgPSBhY2N1cmFjeSkpICsKICBzdGF0X3N1bW1hcnkoCiAgICBnZW9tID0gImJhciIsCiAgICBmdW4ueSA9ICJtZWFuIiwKICAgIGNvbCA9ICJibGFjayIsCiAgICBmaWxsID0gImdyYXk3MCIKICApICsKICAjZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoID0gMCwgdyA9IDAuMikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCBtYXgoZCRjb3JyZWN0LCBuYS5ybSA9IFQpKSwKICAgICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYygwLCAwKSkgKwogIGdlb21fdGV4dChhZXMobGFiZWw9YWNjdXJhY3kpLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjkpLCB2anVzdD0tMC4yNSwgaGp1c3Q9LTAuNjUpICsKICBnZW9tX2Vycm9yYmFyKGRhdGE9c3ViamVjdF9tZWFucywgbWFwcGluZz1hZXMoeD10eXBlLCB5bWluPXVwcGVyLCB5bWF4PWxvd2VyKSwgd2lkdGggPSAwLjMpCmJhcnBsb3QgKyBnZ3RpdGxlKCJBY2N1cmFjeSBieSBUcmlhbCBUeXBlIikKYGBgCgoKIyMgVC1UZXN0IE5TX00gdnMgU19NIGFjY3VyYWN5CmBgYHtyfQp0LnRlc3QoTlNfTSRjb3JyZWN0LCBTX00kY29ycmVjdCkKCnQudGVzdChOU19OTSRydFtOU19OTSRUcmlhbDw1MV0sIE5TX05NJHJ0W05TX05NJFRyaWFsPjUwXSkKCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoU19NX3Jhdywgc3ViamVjdCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShzd2FwQXZnID0gbWVhbihzd2FwQXZnKSwgZmluYWxFYXJuaW5ncyA9IG1lYW4oZmluYWxFYXJuaW5ncywgbmEucm0gPSBUKSkKeCA9IHN1YmplY3RfbWVhbnMkc3dhcEF2Z1tzdWJqZWN0X21lYW5zJHN3YXBBdmc+MS42XQpsZW5ndGgoeCkKbGVuZ3RoKHN1YmplY3RfbWVhbnMkc3ViamVjdCkKYGBgCgojIyBULXRlc3QgTlMgdnMgUyBSVApgYGB7cn0KCmQxIDwtIE5TX00KZDIgPC0gU19NCgojIENyZWF0ZSBJRCBmb3IgZWFjaCBERgpkMSRzdHVkeSA8LSAiU3RhbmRhcmQgTXVsdC4iCmQyJHN0dWR5IDwtICJTd2FwIE11bHQuIgoKIyBOZWVkIHRvIHVuaXF1ZWx5IG51bWJlciBTdWJqZWN0cwpkMiRzdWJqZWN0IDwtIGQyJHN1YmplY3QgKyAxMDAKCiMgQ29uY2F0IERGcwpjb21tb25fY29scyA8LSBpbnRlcnNlY3QoY29sbmFtZXMoZDEpLCBjb2xuYW1lcyhkMikpCmRmID0gcmJpbmQoCiAgZDFbLCBjb21tb25fY29sc10sIAogIGQyWywgY29tbW9uX2NvbHNdCikKCiMgR1JPVVBCWQpzdWJqZWN0X21lYW5zIDwtIGdyb3VwX2J5KGRmLCBzdWJqZWN0LCBzdHVkeSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShhY2N1cmFjeSA9IG1lYW4oY29ycmVjdCwgbmEucm0gPSBUKSwgcnQgPSBtZWFuKHJ0LCBuYS5ybSA9IFQpKQpzdWJqZWN0X21lYW5zCgp0LnRlc3Qoc3ViamVjdF9tZWFucyRydFtzdWJqZWN0X21lYW5zJHN0dWR5ID09ICJTdGFuZGFyZCBNdWx0LiJdLCBzdWJqZWN0X21lYW5zJHJ0W3N1YmplY3RfbWVhbnMkc3R1ZHk9PSJTd2FwIE11bHQuIl0pCmBgYAoKIyBTdW1tZWQgVmFsIHZzLiBBY2N1cmFjeQoKYGBge3J9CmRmIDwtIFNfTQojUlQgdnMuIFN1bW1lZCBWYWx1ZQpnZ3Bsb3QoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWNvcnJlY3QsIGdyb3VwID0gZmFjdG9yKG11bHROdW0pLCBjb2xvdXIgPSBmYWN0b3IobXVsdE51bSkpLCBkZikgKwogICNnZW9tX3Ntb290aChhZXMoeD1zdW1tZWRWYWwsIHk9Y29ycmVjdCwgY29sb3VyID0gImZsaXAiKSwgc3Vic2V0KGRmLCBmbGlwPT0xKSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMywgMykpICArCiAgI2dndGl0bGUoIlN1bW1lZCBWYWx1ZSB2cy4gQWNjdXJhY3kiKQogICNnZW9tX3BvaW50KHNoYXBlPTEpICsgICAgIyBVc2UgaG9sbG93IGNpcmNsZXMKICBnZW9tX3Ntb290aCgpICsgICMgQWRkIGEgbG9lc3Mgc21vb3RoZWQgZml0IGN1cnZlIHdpdGggY29uZmlkZW5jZSByZWdpb24KICB0aGVtZV9taW5pbWFsKCkrCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9Ik5ldCBWYWx1ZSAoJCkiLCBzZXEoLTMsMywwLjUpLCBsaW1pdHMgPSBjKC0zLDMpKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJBY2N1cmFjeSIpICsKICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSkgKwogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZT0iU2V0MiIpICsKICBndWlkZXMoY29sb3VyPWd1aWRlX2xlZ2VuZCh0aXRsZT0iTnVtYmVyIG9mXG5SZS1XZWlnaHRlZFxuQXR0cmlidXRlcyIpKQoKc2V0d2QoIi9Vc2Vycy9kancvRHJvcGJveC9QSEQvUFJFU0VOVEFUSU9OUy8yMDE3X1NORS9QbG90cy8iKQpnZ3NhdmUoIm11bHRWQWNjdXJhY3kucGRmIiwgd2lkdGggPSAyMiwgaGVpZ2h0ID0gMTIsIHVuaXRzID0gImNtIiApCgoKIyBBbHQgdmVyc2lvbnMuLi50cnlpbmcgdG8gdW5kZXJzdGFuZCB0aGUgZGlmZmljdWx0L2FjY3VyYWN5L211bHRpcGxpZXIgYnVzaW5lc3MKCgojIHBsb3QgMXgxLCAyeDIsIDN4MwpkZkVxdWFsTXVsdCA9IGRmW2RmJG11bHQxSG91c2UgPT0gZGYkbXVsdDJGYWNlLCBdCmxlbmd0aChkZkVxdWFsTXVsdCRUcmlhbFtkZkVxdWFsTXVsdCRtdWx0MUhvdXNlID09IDNdKQpnZ3Bsb3QoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWNvcnJlY3QsIGdyb3VwID0gZmFjdG9yKG11bHQxSG91c2UpLCBjb2xvdXIgPSBmYWN0b3IobXVsdDFIb3VzZSkpLCBkZkVxdWFsTXVsdCkgKwogICNnZW9tX3Ntb290aChhZXMoeD1zdW1tZWRWYWwsIHk9Y29ycmVjdCwgY29sb3VyID0gImZsaXAiKSwgc3Vic2V0KGRmLCBmbGlwPT0xKSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMywgMykpICArCiAgI2dndGl0bGUoIlN1bW1lZCBWYWx1ZSB2cy4gQWNjdXJhY3kiKQogICNnZW9tX3BvaW50KHNoYXBlPTEpICsgICAgIyBVc2UgaG9sbG93IGNpcmNsZXMKICBnZW9tX3Ntb290aCgpICsgICMgQWRkIGEgbG9lc3Mgc21vb3RoZWQgZml0IGN1cnZlIHdpdGggY29uZmlkZW5jZSByZWdpb24KICB0aGVtZV9taW5pbWFsKCkrCiAgZ3VpZGVzKGNvbG91cj1ndWlkZV9sZWdlbmQoIlZhbHVlIG9mIFxuTXVsdGlwbGllcnMiKSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lPSJOZXQgVmFsdWUgKCQpIiwgc2VxKC0zLDMsMC41KSwgbGltaXRzID0gYygtMywzKSkrCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiQWNjdXJhY3kiKQoKIyBmaW5lc3NlIGRhdGEKZGZFcXVhbE11bHQkZGlmZmljdWx0eSA9IDEKZGZFcXVhbE11bHQkZGlmZmljdWx0eVthYnMoZGZFcXVhbE11bHQkc3VtbWVkVmFsKSA8MC41XSA9IDIKZGZFcXVhbE11bHQkZGlmZmljdWx0eSA8LSBmYWN0b3IoZGZFcXVhbE11bHQkZGlmZmljdWx0eSkKZGZFcXVhbE11bHQkbXVsdDFIb3VzZSA8LSBmYWN0b3IoZGZFcXVhbE11bHQkbXVsdDFIb3VzZSkKIyBCYXIgcGxvdCBlcXVpdmFsZW50IG11bHRwbGllcnMKZGF0YWMgPC0gc3VtbWFyeVNFd2l0aGluKGRmRXF1YWxNdWx0LCBtZWFzdXJldmFyPSJjb3JyZWN0Iiwgd2l0aGludmFycz1jKCJtdWx0MUhvdXNlIiwiZGlmZmljdWx0eSIpLCBpZHZhcj0ic3ViamVjdCIpCgpnZ3Bsb3QoZGF0YWMsIGFlcyh4PWRpZmZpY3VsdHksIHk9Y29ycmVjdCwgZmlsbD1tdWx0MUhvdXNlKSkgKwogICAgZ2VvbV9iYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpLCBjb2xvdXI9ImJsYWNrIiwgc3RhdD0iaWRlbnRpdHkiKSArCiAgICBnZW9tX2Vycm9yYmFyKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSwgd2lkdGg9LjI1LCBhZXMoeW1pbj1jb3JyZWN0LWNpLCB5bWF4PWNvcnJlY3QrY2kpKSArCiAgICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDAuMCwxKSkgKwogICAgbGFicyh5ID0gIkFjY3VyYWN5IiwgeCA9ICJEaWZmaWN1bHR5IChuZXQgdmFsdWUpIikgKwogICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiMSIgPSAiRWFzeSAoPj0wLjUpIiwgIjIiID0gIkRpZmZpY3VsdCAoPDAuNSkiKSkgKyAgICAKICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKDAsMSwwLjEpKSArCiAgICB0aGVtZV9idygpICsKICAgIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCkpICsKICAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGU9IlBhc3RlbDEiKSArCiAgICBndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9IlZhbHVlIG9mIGJvdGhcbk11bHRpcGxpZXJzIikpCgpzZXR3ZCgiL1VzZXJzL2Rqdy9Ecm9wYm94L1BIRC9QUkVTRU5UQVRJT05TLzIwMTdfU05FL1Bsb3RzIikKZ2dzYXZlKCJFcXVhbE11bHQucGRmIiwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTIsIHVuaXRzID0gImNtIikKCiMgYWNjdXJhY3kgdnMgYW1iaWd1aXR5IGZvciBkaWZmZW50IG51bWJlcnMgb2YgbXVsdGlwbGllcnMKZGYkYWJzRmFjZVZhbCA9IGFicyhkZiRmYWNlVmFsKQpkZiRhYnNIb3VzZVZhbCA9IGFicyhkZiRob3VzZVZhbCkKZGYkYWJzVG90RmFjZVZhbCA9IGFicyhkZiRmYWNlVG90YWwpCmRmJGFic1RvdEhvdXNlVmFsID0gYWJzKGRmJGhvdXNlVG90YWwpCgojIFJlbW92ZSBhYnMgc3VtbWVkIHZhbHVlcyA+MS4wMCBhbmQgPDAuNTAKZEFtYiA8LSBkZlsoZGYkYWJzRmFjZVZhbCA8IDAuNSAmIGRmJGFic0hvdXNlVmFsIDwgMC41KSwgXQpkTmFtYiA8LSBkZlsoZGYkYWJzRmFjZVZhbCA+IDAuNSAmIGRmJGFic0hvdXNlVmFsID4gMC41KSwgXQoKIyBDcmVhdGUgRGlmZmljdWx0eSBMZXZlbCBhbmQgRmFjdG9yIGl0CmRBbWIkZGlmZmljdWx0eSA9IDEgICMgZWFzeSBsZXZlbApkQW1iJGRpZmZpY3VsdHlbZEFtYiRhYnNTdW1tZWRWYWw8MC41XSA9IDIgIyBEaWZmaWN1bHQgbGV2ZWwKZE5hbWIkZGlmZmljdWx0eSA9IDEgICMgZWFzeSBsZXZlbApkTmFtYiRkaWZmaWN1bHR5W2RBbWIkYWJzU3VtbWVkVmFsPDAuNV0gPSAyICMgRGlmZmljdWx0IGxldmVsCmRmJGRpZmZpY3VsdHkgPSAxCmRmJGRpZmZpY3VsdHlbYWJzKGRmJHN1bW1lZFZhbCkgPDAuNV0gPSAyCgojIEZhY3RvciBjb25kaXRpb25zCmRBbWIkbXVsdE51bSA8LSBmYWN0b3IoZEFtYiRtdWx0TnVtKQpkQW1iJGRpZmZpY3VsdHkgPC0gZmFjdG9yKGRBbWIkZGlmZmljdWx0eSkKZE5hbWIkbXVsdE51bSA8LSBmYWN0b3IoZE5hbWIkbXVsdE51bSkKZE5hbWIkZGlmZmljdWx0eSA8LSBmYWN0b3IoZE5hbWIkZGlmZmljdWx0eSkKZGYkbXVsdE51bSA8LSBmYWN0b3IoZGYkbXVsdE51bSkKZGYkZGlmZmljdWx0eSA8LSBmYWN0b3IoZGYkZGlmZmljdWx0eSkKCmRmTm9GbGlwIDwtIGRmW2RmJGZsaXA9PTIsIF0KCiMgQmFyIHBsb3QgbnVtYmVyIG9mIG11bHRpcGxpZXJzCmRhdGFjIDwtIHN1bW1hcnlTRXdpdGhpbihkZiwgbWVhc3VyZXZhcj0iY29ycmVjdCIsIHdpdGhpbnZhcnM9YygibXVsdERpZiIsImRpZmZpY3VsdHkiKSwgaWR2YXI9InN1YmplY3QiKQoKZ2dwbG90KGRhdGFjLCBhZXMoeD1kaWZmaWN1bHR5LCB5PWNvcnJlY3QsIGZpbGw9bXVsdERpZikpICsKICAgIGdlb21fYmFyKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSwgY29sb3VyPSJibGFjayIsIHN0YXQ9ImlkZW50aXR5IikgKwogICAgZ2VvbV9lcnJvcmJhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSksIHdpZHRoPS4yNSwgYWVzKHltaW49Y29ycmVjdC1jaSwgeW1heD1jb3JyZWN0K2NpKSkgKwogICAgY29vcmRfY2FydGVzaWFuKHlsaW09YygwLjAsMSkpICsKICAgIGxhYnMoeSA9ICJBY2N1cmFjeSIsIHggPSAiRGlmZmljdWx0eSAobmV0IHZhbHVlKSIpICsKICAgIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIjEiID0gIkVhc3kgKD49MC41KSIsICIyIiA9ICJEaWZmaWN1bHQgKDwwLjUpIikpICsgICAgCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLDEsMC4xKSkgKwogICAgdGhlbWVfYncoKSArCiAgICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KHNpemU9MTgpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpKSArCiAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJQYXN0ZWwyIikgKwogICAgZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPSJEaWZmZXJlbmNlXG5iZXR3ZWVuXG5NdWx0aXBsaWVycyIpKQoKc2V0d2QoIi9Vc2Vycy9kancvRHJvcGJveC9QSEQvUFJFU0VOVEFUSU9OUy8yMDE3X1NORS9QbG90cyIpCmdnc2F2ZSgiTXVsdERpZi5wZGYiLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMiwgdW5pdHMgPSAiY20iKQoKIyBCYXIgcGxvdCBkaWZmZXJlbmNlIGluIG11bHRpcGxpZXJzCmRhdGFjIDwtIHN1bW1hcnlTRXdpdGhpbihkZiwgbWVhc3VyZXZhcj0iY29ycmVjdCIsIHdpdGhpbnZhcnM9YygibXVsdERpZiIsImRpZmZpY3VsdHkiKSwgaWR2YXI9InN1YmplY3QiKQoKZ2dwbG90KGRhdGFjLCBhZXMoeD1kaWZmaWN1bHR5LCB5PWNvcnJlY3QsIGZpbGw9bXVsdERpZikpICsKICAgIGdlb21fYmFyKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSwgY29sb3VyPSJibGFjayIsIHN0YXQ9ImlkZW50aXR5IikgKwogICAgZ2VvbV9lcnJvcmJhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSksIHdpZHRoPS4yNSwgYWVzKHltaW49Y29ycmVjdC1jaSwgeW1heD1jb3JyZWN0K2NpKSkgKwogICAgY29vcmRfY2FydGVzaWFuKHlsaW09YygwLjUsMSkpICsKICAgIGxhYnMoeSA9ICJBY2N1cmFjeSIsIHggPSAiRGlmZmljdWx0eSAobmV0IHZhbHVlKSIpICsKICAgIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIjEiID0gIkVhc3kgKD4xKSIsICIyIiA9ICJEaWZmaWN1bHQgKDwwLjUpIikpICsgICAgCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLDEsMC4xKSkgKwogICAgdGhlbWVfYncoKSArCiAgICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkRpZmZlcmVuY2UgYmV0d2VlblxuTXVsdGlwbGllcnMiKSAKCiMgcGxvdCBkaWYgMCwgZGlmIDEsIGRpZiAyCmdncGxvdCgpICsKICBnZW9tX3Ntb290aChhZXMoeD1zdW1tZWRWYWwsIHk9Y29ycmVjdCwgZ3JvdXAgPSBmYWN0b3IobXVsdERpZiksIGNvbG91ciA9IGZhY3RvcihtdWx0RGlmKSksIGRmKSArCiAgI2dlb21fc21vb3RoKGFlcyh4PXN1bW1lZFZhbCwgeT1jb3JyZWN0LCBjb2xvdXIgPSAiZmxpcCIpLCBzdWJzZXQoZGYsIGZsaXA9PTEpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0zLCAzKSkgICsKICAjZ2d0aXRsZSgiU3VtbWVkIFZhbHVlIHZzLiBBY2N1cmFjeSIpCiAgI2dlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkgKyAgIyBBZGQgYSBsb2VzcyBzbW9vdGhlZCBmaXQgY3VydmUgd2l0aCBjb25maWRlbmNlIHJlZ2lvbgogIHRoZW1lX21pbmltYWwoKSsKICBndWlkZXMoY29sb3VyPWd1aWRlX2xlZ2VuZCgiRGlmZmVyZW5jZSBiZXR3ZWVuXG5NdWx0aXBsaWVycyIpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9Ik5ldCBWYWx1ZSAoJCkiLCBzZXEoLTMsMywwLjUpLCBsaW1pdHMgPSBjKC0zLDMpKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJBY2N1cmFjeSIpCgojVGVzdCBmb3IgU0lHCnN1bW1hcnkobG0oY29ycmVjdH5zdW1tZWRWYWwgKyBtdWx0TnVtRiArIGZsaXAsIGRmKSkKYGBgCgojIFN1bW1lZCB2YWwgdnMuIFJUCgpgYGB7cn0KZGYgPC0gU19NCgojUlQgdnMuIFN1bW1lZCBWYWx1ZQpnZ3Bsb3QoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PXJ0LCBncm91cCA9IGZhY3RvcihtdWx0TnVtKSwgY29sb3VyID0gZmFjdG9yKG11bHROdW0pKSwgZGYpICsKICAjZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PXJ0LCBjb2xvdXIgPSAiZmxpcCIpLCBzdWJzZXQoZGYsIGZsaXA9PTEpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0zLCAzKSkgICsKICAjZ2d0aXRsZSgiUlQgdnMuIFN1bW1lZCBWYWwiKQogICNnZW9tX3BvaW50KHNoYXBlPTEpICsgICAgIyBVc2UgaG9sbG93IGNpcmNsZXMKICBnZW9tX3Ntb290aCgpICsgICMgQWRkIGEgbG9lc3Mgc21vb3RoZWQgZml0IGN1cnZlIHdpdGggY29uZmlkZW5jZSByZWdpb24KICB0aGVtZV9taW5pbWFsKCkrCiAgZ3VpZGVzKGNvbG91cj1ndWlkZV9sZWdlbmQoIk11bHRpcGxpZXIgXG5Db25kaXRpb24iKSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lPSJOZXQgVmFsdWUgKCQpIiwgc2VxKC0zLDMsMC41KSwgbGltaXRzID0gYygtMywzKSkrCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiUmVhY3Rpb24gVGltZSAocykiKQogIAoKI2NyZWF0ZSBtdWx0bnVtIGFzIGZhY3RvcgpkZiRtdWx0TnVtRiA9IGZhY3RvcihkZiRtdWx0TnVtKQojVGVzdCBmb3IgU0lHCnN1bW1hcnkobG0ocnR+c3VtbWVkVmFsICsgbXVsdE51bUYgKyBmbGlwLCBkZikpCmBgYAoKIyAKCmBgYHtyfQpkZiA8LSBTX00KCiNSVCB2cy4gU3VtbWVkIFZhbHVlIEZpcnN0IEZpeGF0aW9uCmdncGxvdCgpICsKICBnZW9tX3Ntb290aChhZXMoeD1maXJzdFZhbCwgeT1gMV9maXhhdGlvbmAsIGdyb3VwID0gZmFjdG9yKGZpcnN0TXVsdCksIGNvbG91ciA9IGZhY3RvcihmaXJzdE11bHQpKSwgZGYpICsKICAjZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWxvZ1JULCBjb2xvdXIgPSAiZmxpcCIpLCBzdWJzZXQodG90YWxfTV9jbGVhbjMsIGZsaXA9PTEpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0zLCAzKSkgICsKICAjZ2d0aXRsZSgiRmlyc3QgRml4YXRpb24gVGltaW5nIHZzIFRvdGFsIFZhbHVlIikKICAjZ2VvbV9wb2ludChzaGFwZT0xKSArICAgICMgVXNlIGhvbGxvdyBjaXJjbGVzCiAgZ2VvbV9zbW9vdGgoKSArICAjIEFkZCBhIGxvZXNzIHNtb290aGVkIGZpdCBjdXJ2ZSB3aXRoIGNvbmZpZGVuY2UgcmVnaW9uCiAgdGhlbWVfbWluaW1hbCgpKwogIGd1aWRlcyhjb2xvdXI9Z3VpZGVfbGVnZW5kKCJNdWx0aXBsaWVyIFxuQ29uZGl0aW9uIikpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iQXR0cmlidXRlIFdlaWdodGVkIFZhbHVlICgkKSIsIHNlcSgtMywzLDAuNSksIGxpbWl0cyA9IGMoLTMsMykpKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIkF0dHJpYnV0ZSBEd2VsbCBUaW1lIChzKSIpKwogIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgojVGVzdCBmb3IgU0lHCnN1bW1hcnkobG0oYDFfZml4YXRpb25gfmZpcnN0VmFsICsgZmFjdG9yKGZpcnN0TXVsdCksIGRmKSkKCiNSVCB2cy4gU3VtbWVkIFZhbHVlCmdncGxvdCgpICsKICBnZW9tX3Ntb290aChhZXMoeD1zZWNvbmRWYWwsIHk9YDJfZml4YXRpb25gLCBncm91cCA9IGZhY3RvcihzZWNvbmRNdWx0KSwgY29sb3VyID0gZmFjdG9yKHNlY29uZE11bHQpKSwgZGYpICsKICAjZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWxvZ1JULCBjb2xvdXIgPSAiZmxpcCIpLCBzdWJzZXQodG90YWxfTV9jbGVhbjMsIGZsaXA9PTEpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0zLCAzKSkgICsKICAjZ2d0aXRsZSgiU2Vjb25kIEZpeGF0aW9uIFRpbWluZyB2cyBUb3RhbCBWYWx1ZSIpCiAgI2dlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkgKyAjIEFkZCBhIGxvZXNzIHNtb290aGVkIGZpdCBjdXJ2ZSB3aXRoIGNvbmZpZGVuY2UgcmVnaW9uCiAgdGhlbWVfbWluaW1hbCgpKwogIGd1aWRlcyhjb2xvdXI9Z3VpZGVfbGVnZW5kKCJBdHRyaWJ1dGVcbldlaWdodCIpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9IkF0dHJpYnV0ZSBXZWlnaHRlZCBWYWx1ZSAoJCkiLCBzZXEoLTMsMywwLjUpLCBsaW1pdHMgPSBjKC0zLDMpKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJBdHRyaWJ1dGUgRHdlbGwgVGltZSAocykiKSArCiAgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChzaXplPTE0KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwojIFVzZSB0aGUgS3JhamljaCBDbGVhbmVkIERhdGEgIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwojIG1ha2UgdGhlIGRhdGEKZDwtIFNfTV9LCmQkc3ViamVjdCA8LSBmYWN0b3IoZCRzdWJqZWN0KSAKIyBkZWxldGUgYWxsIHJvd3MgYnV0IHNlbGVjdGVkCmRNaWQgPC0gZFsgd2hpY2goZCRmaXhOdW0+MSAmIGQkcmV2Rml4TnVtPjEpLCBdICMgb25seSBtaWRkbGUgZml4YXRpb25zCmRNaWQkY3VycmVudE11bHQgPSAwCmRNaWQkY3VycmVudFZhbCA9IDAKZm9yKCBpIGluIDE6bGVuZ3RoKGRNaWQkdHJpYWwpKXsKICBpZihkTWlkJHJvaVtpXSA9PSAwKXsKICAgIGRNaWQkY3VycmVudE11bHRbaV0gPSBkTWlkJG11bHRGYWNlW2ldCiAgICBkTWlkJGN1cnJlbnRWYWxbaV0gPSBkTWlkJHRvdFZhbEZhY2VbaV0KICB9CiAgaWYoZE1pZCRyb2lbaV0gPT0gMSl7CiAgICBkTWlkJGN1cnJlbnRNdWx0W2ldID0gZE1pZCRtdWx0SG91c2VbaV0KICAgIGRNaWQkY3VycmVudFZhbFtpXSA9IGRNaWQkdG90VmFsSG91c2VbaV0KICB9Cn0KCmRGaW5hbCA8LSBkWyB3aGljaChkJHJldkZpeE51bT09MSksIF0gIyBvbmx5IGZpbmFsIGZpeGF0aW9ucwpkRmluYWwkZmluYWxWYWwgPSAwCmRGaW5hbCRmaW5hbE11bHQgPSAwCmZvciAoaSBpbiAxOmxlbmd0aChkRmluYWwkdHJpYWwpKXsKICBpZihkRmluYWwkcm9pW2ldID09IDApewogICAgZEZpbmFsJGZpbmFsVmFsW2ldIDwtIGRGaW5hbCR0b3RWYWxGYWNlW2ldCiAgICBkRmluYWwkZmluYWxNdWx0W2ldIDwtIGRGaW5hbCRtdWx0RmFjZVtpXQogIH0KICBpZihkRmluYWwkcm9pW2ldID09IDEpewogICAgZEZpbmFsJGZpbmFsVmFsW2ldIDwtIGRGaW5hbCR0b3RWYWxIb3VzZVtpXQogICAgZEZpbmFsJGZpbmFsTXVsdFtpXSA8LSBkRmluYWwkbXVsdEhvdXNlW2ldCiAgfQp9CgojUlQgdnMuIFN1bW1lZCBWYWx1ZTogTWlkZGxlIEZpeGF0aW9ucwpnZ3Bsb3QoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHg9Y3VycmVudFZhbCwgeT1maXhEdXIsIGdyb3VwID0gZmFjdG9yKGN1cnJlbnRNdWx0KSwgY29sb3VyID0gZmFjdG9yKGN1cnJlbnRNdWx0KSksIGRNaWQpICsKICAjZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWxvZ1JULCBjb2xvdXIgPSAiZmxpcCIpLCBzdWJzZXQodG90YWxfTV9jbGVhbjMsIGZsaXA9PTEpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0zLCAzKSkgICsKICAjZ2d0aXRsZSgiU2Vjb25kIEZpeGF0aW9uIFRpbWluZyB2cyBUb3RhbCBWYWx1ZSIpCiAgI2dlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkgKyAjIEFkZCBhIGxvZXNzIHNtb290aGVkIGZpdCBjdXJ2ZSB3aXRoIGNvbmZpZGVuY2UgcmVnaW9uCiAgdGhlbWVfbWluaW1hbCgpKwogIGd1aWRlcyhjb2xvdXI9Z3VpZGVfbGVnZW5kKCJNdWx0aXBsaWVyIFxuQ29uZGl0aW9uIikpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iTmV0IFZhbHVlICgkKSIsIHNlcSgtMywzLDAuNSksIGxpbWl0cyA9IGMoLTMsMykpKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIk1pZGRsZSBGaXhhdGlvbiBEdXJhdGlvbiAocykiKQoKI1JUIHZzLiBTdW1tZWQgVmFsdWU6IEZpbmFsIEZpeGF0aW9uCmdncGxvdCgpICsKICBnZW9tX3Ntb290aChhZXMoeD1maW5hbFZhbCwgeT1maXhEdXIsIGdyb3VwID0gZmFjdG9yKGZpbmFsTXVsdCksIGNvbG91ciA9IGZhY3RvcihmaW5hbE11bHQpKSwgZEZpbmFsKSArCiAgI2dlb21fc21vb3RoKGFlcyh4PXN1bW1lZFZhbCwgeT1sb2dSVCwgY29sb3VyID0gImZsaXAiKSwgc3Vic2V0KHRvdGFsX01fY2xlYW4zLCBmbGlwPT0xKSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMywgMykpICArCiAgI2dndGl0bGUoIlNlY29uZCBGaXhhdGlvbiBUaW1pbmcgdnMgVG90YWwgVmFsdWUiKQogICNnZW9tX3BvaW50KHNoYXBlPTEpICsgICAgIyBVc2UgaG9sbG93IGNpcmNsZXMKICBnZW9tX3Ntb290aCgpICsgIyBBZGQgYSBsb2VzcyBzbW9vdGhlZCBmaXQgY3VydmUgd2l0aCBjb25maWRlbmNlIHJlZ2lvbgogIHRoZW1lX21pbmltYWwoKSsKICBndWlkZXMoY29sb3VyPWd1aWRlX2xlZ2VuZCgiTXVsdGlwbGllciBcbkNvbmRpdGlvbiIpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9Ik5ldCBWYWx1ZSAoJCkiLCBzZXEoLTMsMywwLjUpLCBsaW1pdHMgPSBjKC0zLDMpKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJGaW5hbCBGaXhhdGlvbiBEdXJhdGlvbiAocykiKQoKI1Rlc3QgZm9yIFNJRwpzdW1tYXJ5KGxtKGAyX2ZpeGF0aW9uYH5zZWNvbmRWYWwgKyBzZWNvbmRNdWx0LCBkZikpCgojIFNhdmUgUGxvdCAoZm9yIFNORSkKc2V0d2QoIi9Vc2Vycy9kancvRHJvcGJveC9QSEQvUFJFU0VOVEFUSU9OUy8yMDE3X1NORS9QbG90cy8iKQpnZ3NhdmUoIjJuZEZpeC5wZGYiLCB3aWR0aCA9IDE4LCBoZWlnaHQgPSAxMiwgdW5pdHMgPSAiY20iKQoKYGBgCgojIFNlY29uZCBGaXhhdGlvbiB2cyBTdW1tZWQgVmFsdWUKCmBgYHtyfQpkZiA8LSBTX00KCiNSVCB2cy4gU3VtbWVkIFZhbHVlCmdncGxvdCgpICsKICBnZW9tX3Ntb290aChhZXMoeD1zdW1tZWRWYWwsIHk9YDJfZml4YXRpb25gLCBncm91cCA9IGZhY3RvcihzZWNvbmRNdWx0KSwgY29sb3VyID0gZmFjdG9yKHNlY29uZE11bHQpKSwgZGYpICsKICAjZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWxvZ1JULCBjb2xvdXIgPSAiZmxpcCIpLCBzdWJzZXQodG90YWxfTV9jbGVhbjMsIGZsaXA9PTEpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0zLCAzKSkgICsKICAjZ2d0aXRsZSgiU2Vjb25kIEZpeGF0aW9uIHZzIFN1bW1lZCBWYWx1ZSIpCiAgI2dlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkgICsjIEFkZCBhIGxvZXNzIHNtb290aGVkIGZpdCBjdXJ2ZSB3aXRoIGNvbmZpZGVuY2UgcmVnaW9uCiAgdGhlbWVfbWluaW1hbCgpKwogIGd1aWRlcyhjb2xvdXI9Z3VpZGVfbGVnZW5kKCJNdWx0aXBsaWVyIFxuQ29uZGl0aW9uIikpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iVHJpYWwgTmV0IFZhbHVlICgkKSIsIHNlcSgtMywzLDAuNSksIGxpbWl0cyA9IGMoLTMsMykpKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIkZpeGF0aW9uIER1cmF0aW9uIChzKSIpCiNUZXN0IGZvciBTSUcKc3VtbWFyeShsbShgMl9maXhhdGlvbmB+c3VtbWVkVmFsICsgZmFjdG9yKHNlY29uZE11bHQpLCBkZikpCmBgYAoKIyBRVUVTVElPTk5BSVJFUyAKCmBgYHtyIHBsb3QtZ3BhLWVmZm9ydCwgZWNobz1GQUxTRX0KbG9hZCgiRGF0YS9OU19NLlJkYXRhIikKbG9hZCgiRGF0YS9TX01fcmF3LlJkYXRhIikKCmQxIDwtIE5TX00KZDIgPC0gU19NX3JhdwoKIyBDcmVhdGUgSUQgZm9yIGVhY2ggREYKZDEkc3R1ZHkgPC0gIlN0YW5kYXJkIE11bHQuIgpkMiRzdHVkeSA8LSAiU3dhcCBNdWx0LiIKCmQgPC0gU19NX3JhdwoKI2ltcG9ydCBRdWVzdGlvbm5haXJlIGRhdGEKc2V0d2QoIn4vRHJvcGJveC9QSEQvQ0VORFJJL1Byb2plY3QvQ29kZS9MYWJTaGFyZWRGb2xkZXIvTUFERTAxL0NPREUvR0lUL0JlaGF2aW9yX0FuYWx5c2lzIikKUXVlc3QuZGYgPC0gcmVhZC5jc3YoImNzdl9maWxlcy9RdWVzdGlvbm5haXJlMDFfUmVzdWx0cy5jc3YiKQpRdWVzdC5kZiA8LSBRdWVzdC5kZlsoUXVlc3QuZGYkc3R1ZHlfdmVyc2lvbiA9PSAyKSwgXQoKI21lYW4gUlQgYW5kIEZpbmFsIGVhcm5pbmdzIGJ5IHN1YmplY3QKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShkLCBzdWJqZWN0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHJ0ID0gbWVhbihydCwgbmEucm0gPSBUKSwgCiAgICAgICAgICAgICAgICAgICBmaW5hbEVhcm5pbmdzID0gbWVhbihmaW5hbEVhcm5pbmdzLCBuYS5ybSA9IFQpLCAKICAgICAgICAgICAgICAgICAgIGFjY3VyYWN5ID0gbWVhbihjb3JyZWN0LCBuYS5ybT1UKSkKCnN1YmplY3RfaW5mbyA8LSBncm91cF9ieShRdWVzdC5kZiwgc3ViamVjdCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShncGEgPSBtZWFuKEdQQSwgbmEucm0gPSBUKSwgZWZmb3J0ID0gbWVhbihFZmZvcnQsIG5hLnJtID0gVCksIGd1ZXNzID0gbWVhbihHdWVzc2luZywgbmEucm0gPSBUKSwgY29tcGFyYXRpdmUgPSBtZWFuKENvbXBhcmVkX3RvX290aGVycywgbmEucm0gPSBUKSkKCnN1YmplY3RfbWVhbnMgPC0gbWVyZ2Uoc3ViamVjdF9tZWFucywgc3ViamVjdF9pbmZvLCBieSA9ICJzdWJqZWN0IikKc3ViamVjdF9tZWFucwoKIyMjIEdHUExPVCBSRUdSRVNTSU9OIEZVTkMgaWYgbm90IGxvYWRlZCAjIwpnZ3Bsb3RSZWdyZXNzaW9uIDwtIGZ1bmN0aW9uIChmaXQpIHsKICByZXF1aXJlKGdncGxvdDIpCiAgZ2dwbG90KGZpdCRtb2RlbCwgYWVzX3N0cmluZyh4PW5hbWVzKGZpdCRtb2RlbClbMl0sIHk9bmFtZXMoZml0JG1vZGVsKVsxXSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBzdGF0X3Ntb290aChtZXRob2QgPSAibG0iLCBjb2wgPSAicmVkIikgKwogICAgZ2d0aXRsZSgiVGVzdGluZyIpICsKICAgIGxhYnModGl0bGUgPSBwYXN0ZSh0aXRsZSwgIlxuXG5BZGogUjIgPSAiLHNpZ25pZihzdW1tYXJ5KGZpdCkkYWRqLnIuc3F1YXJlZCwgNSksCiAgICAgICAgICAgICAgICAgICAgICAgIkludGVyY2VwdCA9IixzaWduaWYoZml0JGNvZWZbWzFdXSwgNSksCiAgICAgICAgICAgICAgICAgICAgICAgIlNsb3BlID0iLHNpZ25pZihmaXQkY29lZltbMl1dLCA1KSwKICAgICAgICAgICAgICAgICAgICAgICAiUCA9IixzaWduaWYoc3VtbWFyeShmaXQpJGNvZWZbMiw0XSwgNSkpKQp9Cgp0aXRsZSA9ICJHUEEgdnMgUGVyZm9ybWFuY2UiCmdncGxvdFJlZ3Jlc3Npb24obG0oYWNjdXJhY3l+Z3BhLCBkYXRhID0gc3ViamVjdF9tZWFucykpCgpnZ3Bsb3RSZWdyZXNzaW9uIDwtIGZ1bmN0aW9uIChmaXQpIHsKICByZXF1aXJlKGdncGxvdDIpCiAgZ2dwbG90KGZpdCRtb2RlbCwgYWVzX3N0cmluZyh4PW5hbWVzKGZpdCRtb2RlbClbMl0sIHk9bmFtZXMoZml0JG1vZGVsKVsxXSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBzdGF0X3Ntb290aChtZXRob2QgPSAibG0iLCBjb2wgPSAicmVkIikgKwogICAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiU2VsZi1SZXBvcnRlZCBFZmZvcnQiLCBicmVha3M9c2VxKDEsOSwxKSkgKwogICAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiQWNjdXJhY3kiKSArCiAgICAKICAgIyBnZ3RpdGxlKCJUZXN0aW5nIikgCiAgICBsYWJzKHRpdGxlID0gcGFzdGUodGl0bGUsICJcblxuQWRqIFIyID0gIixzaWduaWYoc3VtbWFyeShmaXQpJGFkai5yLnNxdWFyZWQsIDUpLAogICAgICAgICAgICAgICAgICAgICAgICJJbnRlcmNlcHQgPSIsc2lnbmlmKGZpdCRjb2VmW1sxXV0sIDUpLAogICAgICAgICAgICAgICAgICAgICAgICJTbG9wZSA9IixzaWduaWYoZml0JGNvZWZbWzJdXSwgNSksCiAgICAgICAgICAgICAgICAgICAgICAgIlAgPSIsc2lnbmlmKHN1bW1hcnkoZml0KSRjb2VmWzIsNF0sIDUpKSkKfQoKdGl0bGUgPSAiU2VsZi1SZXBvcnRlZCBFZmZvcnQgdnMgUGVyZm9ybWFuY2UiCmdncGxvdFJlZ3Jlc3Npb24obG0oYWNjdXJhY3l+ZWZmb3J0LCBkYXRhID0gc3ViamVjdF9tZWFucykpCgpzdWJqZWN0X21lYW5zCgpgYGAKCgojIyBCb3hwbG90IG9mIHVuZmlsdGVyZWQgZGF0YQoKWW91IGNhbiBzZWUgd2hpY2ggcGVvcGxlIHdlcmUgbm90IHRyeWluZzoKCmBgYHtyIFJULXVuZmlsdGVyZWQsIGVjaG89VFJVRX0KZGYgPC0gU19NX3JhdwoKIyBGaWx0ZXIgb3V0IGV4dHJlbWVseSBsb25nIHJ0IHRpbWVzCmRmIDwtIGRmWyEoZGYkcnQ+MTApLF0KCmJveHBsb3QocnQgfiBmYWN0b3Ioc3ViamVjdCksCiAgICAgICAgdmFyd2lkdGggPSBUUlVFLCB4bGFiID0gInN1YmplY3QiLAogICAgICAgIG1haW4gPSAiQm94cGxvdCBvZiBSVCBjb25kaXRpb25hbCBvblwKICAgICAgICBzdWJqZWN0IiwgeWxhYiA9ICJSVCIsIGRhdGEgPSBkZikKYGBgCgoKIyMjIFBsb3R0aW5nIG1lYW4gUlQgdnMuIEVhcm5pbmdzICh1bmZpbHRlcmVkIGRhdGEpOgoKYGBge3IgUlRfRWFybmluZ3MtdW5maWx0ZXJlZCwgZWNobz1GQUxTRX0KCiMjIyMjIyMjIyMjIyMjIyMjCiMgRlVOQ1RJT04gVE8gUFVMTCBEQVRBIE9VVCBPRiBMTQojIyMjIyMjIyMjIyMjIyMjIwoKZ2dwbG90UmVncmVzc2lvbiA8LSBmdW5jdGlvbiAoZml0KSB7CiAgcmVxdWlyZShnZ3Bsb3QyKQogIGdncGxvdChmaXQkbW9kZWwsIGFlc19zdHJpbmcoeD1uYW1lcyhmaXQkbW9kZWwpWzJdLCB5PW5hbWVzKGZpdCRtb2RlbClbMV0pKSArCiAgICBnZW9tX3BvaW50KCkgKwogICAgc3RhdF9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sID0gInJlZCIpICsKICAgIGdndGl0bGUoIlRlc3RpbmciKSArCiAgICBsYWJzKHRpdGxlID0gcGFzdGUodGl0bGUsICJcblxuQWRqIFIyID0gIixzaWduaWYoc3VtbWFyeShmaXQpJGFkai5yLnNxdWFyZWQsIDUpLAogICAgICAgICAgICAgICAgICAgICAgICJJbnRlcmNlcHQgPSIsc2lnbmlmKGZpdCRjb2VmW1sxXV0sIDUpLAogICAgICAgICAgICAgICAgICAgICAgICJTbG9wZSA9IixzaWduaWYoZml0JGNvZWZbWzJdXSwgNSksCiAgICAgICAgICAgICAgICAgICAgICAgIlAgPSIsc2lnbmlmKHN1bW1hcnkoZml0KSRjb2VmWzIsNF0sIDUpKSkKfQoKIyMjIyMjIyMjIyMjIyMjIyMKIyBJTklUSUFMIFBMT1RTCiMjIyMjIyMjIyMjIyMjIyMjCgojU2VsZWN0IGRhdGFmcmFtZSB0byB1c2UKZCA8LSBTX01fcmF3CmQkY29ycmVjdCA9IGFzLm51bWVyaWMoZCRjb3JyZWN0KSAtIDEgI21ha2UgYWNjdXJhY3kgbnVtZXJpYwoKI21lYW4gUlQgYW5kIEZpbmFsIGVhcm5pbmdzIGJ5IHN1YmplY3QKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShkLCBzdWJqZWN0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHJ0ID0gbWVhbihydCwgbmEucm0gPSBUKSwgZmluYWxFYXJuaW5ncyA9IG1lYW4oZmluYWxFYXJuaW5ncywgbmEucm0gPSBUKSkKCnRpdGxlID0gIkVhcm5pbmdzIGFzIHJlbGF0ZWQgdG8gTWVhbiBSVCIKZ2dwbG90UmVncmVzc2lvbihsbShmaW5hbEVhcm5pbmdzfnJ0LCBkYXRhID0gc3ViamVjdF9tZWFucykpCgojbWVhbiBSVCBhbmQgQWNjdXJhY3kgYnkgc3ViamVjdApzdWJqZWN0X21lYW5zIDwtIGdyb3VwX2J5KGQsIHN1YmplY3QpICU+JQogIGRwbHlyOjpzdW1tYXJpemUoZmluYWxFYXJuaW5ncyA9IG1lYW4oZmluYWxFYXJuaW5ncywgbmEucm0gPSBUKSwgYWNjdXJhY3kgPSBtZWFuKGFzLm51bWVyaWMoY29ycmVjdCksIG5hLnJtID0gVCkpCgp0aXRsZSA9ICJFYXJuaW5ncyBhcyByZWxhdGVkIHRvICUgQ29ycmVjdCIKZ2dwbG90UmVncmVzc2lvbihsbShmaW5hbEVhcm5pbmdzfmFjY3VyYWN5LCBkYXRhID0gc3ViamVjdF9tZWFucykpCgojbWVhbiBSVCBhbmQgRmluYWwgZWFybmluZ3MgYnkgc3ViamVjdApzdWJqZWN0X21lYW5zMiA8LSBncm91cF9ieShkLCBzdWJqZWN0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGZsaXBzID0gbWVhbihzd2FwQW1vdW50LCBuYS5ybSA9IFQpLCBmaW5hbEVhcm5pbmdzID0gbWVhbihmaW5hbEVhcm5pbmdzLCBuYS5ybSA9IFQpKQoKdGl0bGUgPSAiRWFybmluZ3MgYXMgcmVsYXRlZCB0byBOdW1iZXIgb2YgSW1hZ2UgU3dhcHMiCmdncGxvdFJlZ3Jlc3Npb24obG0oZmluYWxFYXJuaW5nc35mbGlwcywgZGF0YSA9IHN1YmplY3RfbWVhbnMyKSkKYGBgCgoKCiMjIyBLTWVhbnMgdG8gRGl2aWRlIGludG8gZ3JvdXBzIGJhc2VkIG9uIHN3YXBzLyQkICh1bmZpbHRlcmVkIGRhdGEpOgoKYGBge3IgSy1NZWFuczIsIGVjaG89RkFMU0V9CnN1YmplY3RfbWVhbnMyIDwtIGdyb3VwX2J5KGQsIHN1YmplY3QpICU+JQogIGRwbHlyOjpzdW1tYXJpemUoZmxpcHMgPSBtZWFuKHN3YXBBbW91bnQsIG5hLnJtID0gVCksIGZpbmFsRWFybmluZ3MgPSBtZWFuKGZpbmFsRWFybmluZ3MsIG5hLnJtID0gVCkpCgpzdWJqZWN0X21lYW5zMiRzdWJqZWN0ID0gTlVMTAoKI0NsdXN0ZXIgaW50byAyIGdyb3VwcwpyZXN1bHRzIDwtIGttZWFucyhzdWJqZWN0X21lYW5zMiwgMikKCnBsb3QoeCA9IHN1YmplY3RfbWVhbnMyJGZsaXBzLCB5ID0gc3ViamVjdF9tZWFuczIkZmluYWxFYXJuaW5ncywKICAgICBjb2wgPSByZXN1bHRzJGNsdXN0ZXIsCiAgICAgbWFpbiA9ICJDbHVzdGVyaW5nIGJhc2VkIG9uIFN3YXBzICYmIERvbGxhcnMiLAogICAgIHlsYWIgPSAiRmluYWwgRWFybmluZ3MiLAogICAgIHhsYWIgPSAiU3dhcHMiKQoKcmVzdWx0cwpgYGAKClRlbmRzIHRvIGluY2x1ZGUgc29tZSBwZW9wbGUgd2hvIGVhcm5lZCBvdmVyICQ1MCBidXQgbmV2ZXIgbG9va2VkIGF0IHRoZSBzZWNvbmQgaW1hZ2UuLi4KCmBgYHtyIEstTWVhbnMzLCBlY2hvPUZBTFNFfQojU2VsZWN0IGRhdGFmcmFtZSB0byB1c2UKZCA8LSBTX01fcmF3CgojbWVhbiBSVCBhbmQgRmluYWwgZWFybmluZ3MgYnkgc3ViamVjdApzdWJqZWN0X21lYW5zMiA8LSBncm91cF9ieShkLCBzdWJqZWN0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGFjY3VyYWN5ID0gbWVhbihhY2N1cmFjeSwgbmEucm0gPSBUKSwgZmluYWxFYXJuaW5ncyA9IG1lYW4oZmluYWxFYXJuaW5ncywgbmEucm0gPSBUKSkKCiNDbHVzdGVyIGludG8gMiBncm91cHMKc3ViamVjdF9tZWFuczIkc3ViamVjdCA9IE5VTEwKCnJlc3VsdHMgPC0ga21lYW5zKHN1YmplY3RfbWVhbnMyLCAyKQoKcGxvdCh4ID0gc3ViamVjdF9tZWFuczIkYWNjdXJhY3ksIHkgPSBzdWJqZWN0X21lYW5zMiRmaW5hbEVhcm5pbmdzLAogICAgIGNvbCA9IHJlc3VsdHMkY2x1c3RlciwKICAgICBtYWluID0gIkNsdXN0ZXJpbmcgYmFzZWQgb24gQWNjdXJhY3kgJiYgRWFybmluZ3MiLAogICAgIHlsYWIgPSAiRmluYWwgRWFybmluZ3MiLAogICAgIHhsYWIgPSAiQWNjdXJhY3kiKQoKcmVzdWx0cwpgYGAKCiMjIyBDbGVhbiBkYXRhIGJ5IHJlbW92aW5nIHBlb3BsZSB3aXRoIGxlc3MgdGhhbiAxLjUgc3dhcCBhdmVyYWdlIGFuZCBsZXNzIHRoYW4gJDAgZWFybmluZ3MKCmBgYHtyIENsZWFuLWRhdGEsIGVjaG89VFJVRX0KI3JlbW92ZSBlYXJuaW5ncyBiZWxvdyAwCnRvdGFsX01fY2xlYW4yIDwtIFNfTV9yYXdbIShTX01fcmF3JGZpbmFsRWFybmluZ3M8MCksXQojcmVtb3ZlIGZsaXAgYXZncyBsZXNzIHRoYW4gMS41CnRvdGFsX01fY2xlYW4yIDwtIHRvdGFsX01fY2xlYW4yWyEodG90YWxfTV9jbGVhbjIkZmxpcEF2ZzwxLjUpLF0KbGVuZ3RoKHVuaXF1ZSh0b3RhbF9NX2NsZWFuMiRzdWJqZWN0KSkKCiNNT1JFIEFHUkVTU0lWRTogUkVNT1ZFIEJFTE9XIDc1JQp0b3RhbF9NX2NsZWFuMyA8LSBTX01fcmF3WyEoU19NX3JhdyRhY2N1cmFjeTwwLjc1KSxdCmxlbmd0aCh1bmlxdWUodG90YWxfTV9jbGVhbjMkc3ViamVjdCkpCmBgYAoKVGFraW5nIG91dCB0aG9zZSB0aGF0IHN3YXBwZWQgaW1hZ2VzIGxlc3MgdGhhbiAyIHRpbWVzIGFuZCBlYXJuZWQgbGVzcyB0aGFuICQwIGxlYXZlcyAqMjQgc3ViamVjdHMqClRha2luZyBvdXQgdGhvc2UgdGhhdCBoYWQgYW4gYWNjdXJhY3kgb2YgYmVsb3cgNzUlIGxlYXZlcyAqMjEgc3ViamVjdHMqCgoKIyMgQm94cGxvdCBvZiBmaWx0ZXJlZCBkYXRhCgpBIGxvdCBvZiB2YXJpYXRpb24gaW4gYXZnLiBSVCBhbmQgdGhlIHZhcmlhbmNlIG9mIFJUcy4gNCw3IGFuZCAyMyBzZWVtIHRvIGhhdmUgcGFydGljdWxhcmx5IGxvdyB2YXJpYW5jZS4KCmBgYHtyIFJULWZpbHRlcmVkLCBlY2hvPVRSVUV9CmJveHBsb3QocnQgfiBmYWN0b3Ioc3ViamVjdCksCiAgICAgICAgdmFyd2lkdGggPSBUUlVFLCB4bGFiID0gInN1YmplY3QiLAogICAgICAgIG1haW4gPSAiQm94cGxvdCBvZiBSVCBjb25kaXRpb25hbCBvblwKICAgICAgICBzdWJqZWN0IiwgeWxhYiA9ICJSVCIsIGRhdGEgPSBTX00pCgpgYGAKCiMjQ2hlY2sgUlQgZGlzdHJpYnV0aW9uCmBgYHtyIHBsb3QtUlR2VmFsdWUyLCBlY2hvPUZBTFNFfQojUlQKaGlzdChTX00kcnQsIGJyZWFrcyA9IDUwKQphYmxpbmUodiA9IG1lYW4oU19NJHJ0KSwKICAgICAgIGNvbCA9ICJyb3lhbGJsdWUiLAogICAgICAgbHdkID0gMikKCiNtZWRpYW4gbGluZQphYmxpbmUodiA9IG1lZGlhbihTX00kcnQpLAogICAgICAgY29sID0gInJlZCIsCiAgICAgICBsd2QgPSAyKQoKI0xFR0VORApsZWdlbmQoeCA9ICJ0b3ByaWdodCIsCiAgICAgICBjKGFzLmV4cHJlc3Npb24oYnF1b3RlKE1lYW4gPT0gLihtZWFuKFNfTSRydCkpKSksIGFzLmV4cHJlc3Npb24oYnF1b3RlKE1lZGlhbiA9PSAuKG1lZGlhbihTX00kcnQpKSkpKSwKICAgICAgIGNvbCA9IGMoInJveWFsYmx1ZSIsICJyZWQiKSwKICAgICAgIGx3ZCA9IGMoMiwgMiwgMikpCmBgYAoKU2tld2VkIHJpZ2h0LCBhcyBpcyB0eXBpY2FsIG9mIFJULiAKCiMjSGlzdG9ncmFtIG9mIAoKYGBge3IgcGxvdFJUdkZyZXF1ZW5jeS1jb3JyZWN0LCBlY2hvPUZBTFNFfQojZmluZCBzdWJqZWN0IGFjY3J1YWN5ICh1bmNsZWFuZWQpCmFjY3VyYWN5ID0gdGFwcGx5KFNfTSRjb3JyZWN0PT0xLCBTX00kc3ViamVjdCwgbWVhbikKCiNoaXN0cyBvZiBydCBiYXNlZCBvbiBjb25ncnVlbnQgYW5kIGluY29uZ3J1ZW50IHRyaWFscwpoaXN0KFNfTVtTX00kY29ycmVjdD09MSwgXSRydCwKICAgY29sPXJnYigxLDAsMCwwLjUpLCBicmVha3M9c2VxKDAsMTAsMC4xKSwgeWxpbT1jKDAsMzAwKSwgeGxhYj0iUmVhY3Rpb24gVGltZSAocykiLCBtYWluID0gIiIpCmFibGluZSh2PW1lZGlhbihTX01bU19NJGNvcnJlY3Q9PTEsIF0kcnQpLCBjb2w9InJlZCIpCmhpc3QoU19NW1NfTSRjb3JyZWN0PT0wLCBdJHJ0LAogICBjb2w9cmdiKDAsMCwxLDAuNSksIGJyZWFrcz1zZXEoMCwxMCwwLjEpLCB5bGltPWMoMCwzMDApLCBhZGQ9VCkKYWJsaW5lKHY9bWVkaWFuKFNfTVtTX00kY29ycmVjdD09MCwgXSRydCksIGNvbD0iYmx1ZSIpCgpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgYygiQ29ycmVjdCIsICJJbmNvcnJlY3QiKSwgZmlsbD1jKHJnYigxLDAsMCwwLjUpLCByZ2IoMCwwLDEsMC41KSkpCmxlZ2VuZCgidG9wcmlnaHQiLAogICAgICAgYyhhcy5leHByZXNzaW9uKGJxdW90ZShDb3JyZWN0X01lZGlhbiA9PSAuKG1lZGlhbihTX01bU19NJGNvcnJlY3Q9PTEsIF0kUlQpKSkpLCBhcy5leHByZXNzaW9uKGJxdW90ZShJbmNvcnJlY3RfTWVkaWFuID09IC4obWVkaWFuKFNfTVtTX00kY29ycmVjdD09MCwgXSRSVCkpKSkpLAogICAgICAgY29sID0gYygicmVkIiwgImJsdWUiKSwKICAgICAgIGx3ZCA9IGMoMiwgMiwgMSkpCmBgYAojIyBSVHMgQnkgU3ViamVjdApgYGB7ciBmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTE2fQoKZyA9IGdncGxvdChTX00sIGFlcyh4ID0gcnQpKSArIGdlb21faGlzdG9ncmFtKCkgCgpnICsgZmFjZXRfd3JhcCh+IHN1YmplY3QsIG5jb2w9MikKCmBgYAoKCiMjIEhpc3Qgb2YgTWlkZGxlIEZpeGF0aW9ucyAoQWxsIFN1YmplY3RzKQpgYGB7cn0KZGYgPC0gU19NCgojY3JlYXRlIHZlcnNpb24gb2YgZGF0YXNldCB3aXRoIG9ubHkgbWlkZGxlIGZpeGF0aW9ucyAod2UgdXNlIHRoaXMgbGF0ZXIgZm9yIGRyYXdpbmcgcmFuZG9tIG1pZGRsZSBmaXhhdGlvbnMpCgojIG1ha2Ugc3VyZSBldmVyeSB0cmlhbCBlbmRzIHdpdGggYW4gTkEgdmFsCmRmJGAxNF9maXhhdGlvbmAgPC0gTkEgICAgIAoKIyBmaW5kIGNvbCBOdW1iZXIgb2YgZmlyc3QgZml4CiMgQ2hlY2sgdGhhdCB3ZSBhcmUgc3RhcnRpbmcgYXQgY29sdW1uIGZpeCMxCmZpcnN0Rml4ID0gd2hpY2gobmFtZXMoZGYpID09ICIxX2ZpeGF0aW9uIikKCiMgZmluZCB0aGUgZmlyc3QgTkEgdmFsIGluIGVhY2ggcm93Cm5hVmFsIDwtIHZlY3Rvcihtb2RlPSJudW1lcmljIiwgbGVuZ3RoPTApCmZvcih4IGluIDE6bGVuZ3RoKGRmJFRyaWFsKSl7CiAgbmFWYWxbeF0gPC0gbWluKHdoaWNoKGlzLm5hKGRmW3gsXSkpKQp9CgojIGlmIG5hVmFsID4zOSB0aGVuIHRoZXJlIHdlcmUgYXQgbGVhc3QgMyBmaXhhdGlvbnMKbWlkRml4IDwtIHZlY3Rvcihtb2RlID0gIm51bWVyaWMiLCBsZW5ndGggPSAwKQpmb3IoeCBpbiAxOmxlbmd0aChkZiRUcmlhbCkpewogIGlmKG5hVmFsW3hdPihmaXJzdEZpeCsyKSl7CiAgICBmb3IoeSBpbiAoZmlyc3RGaXgrMSk6KG5hVmFsW3hdLTIpKXsKICAgICAgdmFsID0gZGZbeCx5XQogICAgICBtaWRGaXggPC0gYyhtaWRGaXgsIHZhbCkKICAgIH0KICB9Cn0KCm1lYW4obWlkRml4KQptZWRpYW4obWlkRml4KQoKU19NJGZpbmFsRml4Cmhpc3QobWlkRml4LAogICBjb2w9cmdiKDEsMCwwLDAuNSksIGJyZWFrcz1zZXEoMCw5LDAuMSksIHlsaW09YygwLDkwMCksIHhsYWI9IlJUIiwgbWFpbiA9ICJNaWRkbGUgRml4YXRpb25zIikKI2FibGluZSh2PW1lZGlhbihtaWRGaXgpLCBjb2w9ImJsdWUiKQoKbGVnZW5kKCJ0b3ByaWdodCIsCiAgICAgICBjKGFzLmV4cHJlc3Npb24oYnF1b3RlKE1pZEZpeF9NZWRpYW4gPT0gLihtZWRpYW4obWlkRml4KSkpKSksCiAgICAgICBjb2wgPSBjKCJibHVlIiksCiAgICAgICBsd2QgPSBjKDIsIDIsIDEpKQoKYGBgCgojIyBIaXN0IG9mIE1pZGRsZSBGaXhhdGlvbnMgYnkgU3ViamVjdApgYGB7ciBmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTE2fQpsb2FkKCJEYXRhL1NfTV9LLlJkYXRhIikKZGYgPC0gU19NX0sKCiMgUkVNT1ZFIEZpcnN0IGFuZCBMYXN0IEZpeGF0aW9ucwpkZiA8LSBkZlsoZGYkZml4TnVtIT0xICYgZGYkcmV2Rml4TnVtIT0xKSxdCgojIFNVQkpFQ1QgTUVBTlMgQU5EIFNEIEFORCBGSVggIwpzdWJqZWN0X21lYW5zIDwtIGdyb3VwX2J5KGRmLCBzdWJqZWN0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKG1lZGlhbiA9IG1lZGlhbihydCwgbmEucm0gPSBUKSwgbWVhbiA9IG1lYW4ocnQsIG5hLnJtID0gVCksIHNkID0gc2QocnQsIG5hLnJtID0gVCksIGNvdW50ID0gbGVuZ3RoKHJ0KSkKc3ViamVjdF9tZWFucwoKIyBQbG90IEhpc3QKZyA9IGdncGxvdChkZiwgYWVzKHggPSBydCkpICsgCiAgZ2VvbV9oaXN0b2dyYW0oZGF0YSA9IHRyYW5zZm9ybShkZiwgc3ViamVjdCA9IE5VTEwpLCBmaWxsID0gImJsdWUiLCBhbHBoYSA9IDAuNCkgKwogIGdlb21faGlzdG9ncmFtKCkgCgpnICsgZmFjZXRfd3JhcCh+IHN1YmplY3QsIG5jb2w9MikKCiMgUExvdCBEZW5zaXR5CiMgImFkanVzdCIgY29udHJvbHMgdGhlIGJhbmR3aWR0aAphbGxGaXggPSB0cmFuc2Zvcm0oZGYsIHN1YmplY3QgPSBOVUxMKQoKZyA9IGdncGxvdChkZiwgYWVzKHg9cnQpKSArIAogIGdlb21fZGVuc2l0eShkYXRhID0gYWxsRml4LCBhZXMoYWxwaGEgPSAwLjUsIGZpbGwgPSAiZ3JvdXAiKSkgKwogIGdlb21fZGVuc2l0eShhZXMoYWxwaGEgPSAwLjUsIGZpbGwgPSAic3ViamVjdCIpKSArCiAgI2dlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9bWVhbihydCkpLCBjb2xvcj0iYmxhY2siLCBzaXplPTEpICsKICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkRlbnNpdHkgUGxvdCIsIAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoZ3JvdXAgPSAiYmx1ZSIsIHN1YmplY3QgPSAicmVkIikpCgphcHBlbmRlciA8LSBmdW5jdGlvbihzdHJpbmcsIHByZWZpeCA9ICJTdWJqZWN0OiAiLCBzdWZmaXggPSAiICBNZWFuOiAiLCBtZWFuID0gc3BlY2lmeV9kZWNpbWFsKHN1YmplY3RfbWVhbnMkbWVhbltzdWJqZWN0X21lYW5zJHN1YmplY3QgPT0gKGFzLm51bWVyaWMoc3RyaW5nKSldLDIpKSBwYXN0ZTAocHJlZml4LCBzdHJpbmcsIHN1ZmZpeCwgbWVhbikKICAgICAgICAgICAgICAKZyArIGZhY2V0X3dyYXAofiBzdWJqZWN0LCBuY29sPTIsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoYXBwZW5kZXIpKSArCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjEpKSArCiAgZ2d0aXRsZSgiU3ViamVjdCB2cyBHcm91cCBNaWRkbGUgRml4YXRpb25zIChpbiBzKSIpCgoKYGBgCgoKIyNMb2cgUlQgaGlzdG9ncmFtCmBgYHtyIHBsb3QtUlR2VmFsdWUsIGVjaG89RkFMU0V9CiNSVAoKaGlzdChsb2codG90YWxfTV9jbGVhbjMkUlQpLCBicmVha3MgPSA1MCkKYWJsaW5lKHYgPSBtZWFuKGxvZyh0b3RhbF9NX2NsZWFuMyRSVCkpLAogICAgICAgY29sID0gInJveWFsYmx1ZSIsCiAgICAgICBsd2QgPSAyKQoKI21lZGlhbiBsaW5lCmFibGluZSh2ID0gbWVkaWFuKGxvZyh0b3RhbF9NX2NsZWFuMyRSVCkpLAogICAgICAgY29sID0gInJlZCIsCiAgICAgICBsd2QgPSAyKQoKI0xFR0VORApsZWdlbmQoeCA9ICJ0b3ByaWdodCIsCiAgICAgICBjKGFzLmV4cHJlc3Npb24oYnF1b3RlKE1lYW4gPT0gLihtZWFuKGxvZyh0b3RhbF9NX2NsZWFuMyRSVCkpKSkpLCBhcy5leHByZXNzaW9uKGJxdW90ZShNZWRpYW4gPT0gLihtZWRpYW4obG9nKHRvdGFsX01fY2xlYW4zJFJUKSkpKSkpLAogICAgICAgY29sID0gYygicm95YWxibHVlIiwgInJlZCIpLAogICAgICAgbHdkID0gYygyLCAyLCAyKSkKYGBgCgoKIyNQbG90IFJUIHZzIFN1bW1lZCBWYWx1ZSAKYGBge3IgcGxvdC1ydFZhbDIsIGVjaG89RkFMU0V9CmQgPC0gU19NCgojUlQgdnMuIFN1bW1lZCBWYWx1ZQpnZ3Bsb3QoZCwgYWVzKHg9c3VtbWVkVmFsLCB5PXJ0KSkgKwogIGdlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkgICMgQWRkIGEgbG9lc3Mgc21vb3RoZWQgZml0IGN1cnZlIHdpdGggY29uZmlkZW5jZSByZWdpb24KYGBgCgojI1Bsb3QgTE9HIFJUIHZzIFN1bW1lZCBWYWx1ZSAKYGBge3IgcGxvdC1sb2ctcnRWYWwxLCBlY2hvPUZBTFNFfQoKI1JUIHZzLiBTdW1tZWQgVmFsdWUKZ2dwbG90KHRvdGFsX01fY2xlYW4zLCBhZXMoeD1zdW1tZWRWYWwsIHk9bG9nUlQpKSArCiAgZ2VvbV9wb2ludChzaGFwZT0xKSArICAgICMgVXNlIGhvbGxvdyBjaXJjbGVzCiAgZ2VvbV9zbW9vdGgoKSAgIyBBZGQgYSBsb2VzcyBzbW9vdGhlZCBmaXQgY3VydmUgd2l0aCBjb25maWRlbmNlIHJlZ2lvbgpgYGAKCiMjUGxvdCBBY2N1cmFjeSB2cyBEaWZmaWN1bHR5CmBgYHtyIHBsb3QtYWNjdXJhY3lEaWZmaWN1bHR5LCBlY2hvPUZBTFNFfQojREVMRVRFIFRISVMKI3RvdGFsX01fY2xlYW4zJGFic1N1bW1lZFZhbCA8LSBhYnModG90YWxfTV9jbGVhbjMkc3VtbWVkVmFsKQoKI0tlcm5hbCBEZW5zaXR5IG9mIGFicyhTdW1tZWRWYWwpCmQgPC0gZGVuc2l0eSh0b3RhbF9NX2NsZWFuMyRhYnNTdW1tZWRWYWwpCnBsb3QoZCwgbWFpbiA9ICJLZXJuZWwgRGVuc2l0eSBvZiBDb21iaW5lZCBWYWx1ZSIpCgp0aXRsZSA9ICJBY2N1cmFjeSB2cy4gRGlmZmljdWx0eSIKZ2dwbG90UmVncmVzc2lvbihsbShjb3JyZWN0fmFic0RpZmYsIGRhdGEgPSB0b3RhbF9NX2NsZWFuMykpCmBgYAoKIyNIaXN0IG9mIEFjY3VyYWN5IHZzIERpZmZpY3VsdHkKYGBge3IgaGlzdC1hY2N1cmFjeURpZmZpY3VsdHksIGVjaG89RkFMU0V9CgpkIDwtIFNfTQojZCRiaW5zIDwtIGN1dChkJGFic1N1bW1lZFZhbCwgYnJlYWtzID0gMTAsIGRpZy5sYWIgPSAyKQpkJGJpbnMgPC0gY3V0KGQkYWJzU3VtbWVkVmFsLCBzZXEoZnJvbT0wLCB0bz02LCBieT0wLjUpLCBkaWcubGFiID0gMikKCiNxcGxvdChiaW5zLCBjb3JyZWN0LCBkYXRhID0gZCwgc3RhdCA9ICJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIpCgptIDwtIHRhcHBseShkJGNvcnJlY3QsIGQkYmlucywgbWVhbikKc2QgPC0gdGFwcGx5KGQkY29ycmVjdCwgZCRiaW5zLCBzZCkKZGYgPC0gZGF0YS5mcmFtZShtZWFuLnkgPSBtLCBzZCA9IHNkLCBiaW4gPSBuYW1lcyhtKSkKIyBQb2ludHM6CiNnZ3Bsb3QoZGYsIGFlcyh4PWJpbiwgeT1tZWFuLnksCiMgICAgICAgICAgICAgIHltaW4gPSBtZWFuLnkgLSAxLjk2KnNkLAojICAgICAgICAgICAgICB5bWF4ID0gbWVhbi55ICsgMS45NipzZCkpICsKIyAgZ2VvbV9lcnJvcmJhcigpICsgZ2VvbV9wb2ludChzaXplPTMpCgpnZ3Bsb3QoZGYsIGFlcyh4PWJpbiwgeT1tZWFuLnkpKSArCiAgbGFicyh4ID0gImFic1N1bW1lZFZhbCIsIHkgPSAiTWVhbiBBY2N1cmFjeSBSYXRlIiwgdGl0bGUgPSAiQWNjdXJhY3kgdnMgRGlmZmljdWx0eSIpICsKICBnZW9tX3BvaW50KHNpemU9MykKYGBgCgojIyBTSUdNT0lEIG9mIEFDQ0VQVCBWUyBWQUxVRQoKYGBge3J9CmQgPC0gU19NCgpwbG90KGQkc3VtbWVkVmFsLCBkJGNob2ljZSwKICAgICBtYWluID0gIkNob2ljZSB2cy4gU3VtbWVkIFZhbCIsCiAgICAgeGxhYj0iU3VtbWVkIFZhbCIsIHlsYWI9IlAgKEFjY2VwdCkiLAogICAgIHhsaW09YygtMywgMykpCgptb2RlbCA8LSBnbG0oY2hvaWNlIH4gc3VtbWVkVmFsLCBkYXRhPWQsIGZhbWlseT1iaW5vbWlhbChsaW5rID0gbG9naXQpKQpzdW1tYXJ5KG1vZGVsKQoKeHYgPC0gc2VxKG1pbihkJHN1bW1lZFZhbCksIG1heChkJHN1bW1lZFZhbCksIDAuMDEpCnl2IDwtIHByZWRpY3QobW9kZWwsbGlzdChzdW1tZWRWYWw9eHYpLCB0eXBlPSJyZXNwb25zZSIpCgphYmxpbmUoMC41LDAsIGx0eT0yKQpsaW5lcyh4dix5dikKCiNGaW5kIHRoZSBpbmZsZWN0aW9uIHBvaW50IHdoZXJlIHRoZXJlIGlzIGEgNTAvNTAgcHJvYmFiaWxpdHkgb2Ygc3ViamVjdCBhY2NlcHRpbmcuCnAgPC0gMC41CnggPC0gKGxvZyhwLygxLXApKSAtIGNvZWYobW9kZWwpWzFdKSAvIGNvZWYobW9kZWwpWzJdCngKYGBgCgojIyBGaW5hbCBGaXggdnMgQ2hvaWNlCgojVFdPIERJRkZJQ1VMVFkgQ09ORElUSU9OUyAoSGFyZC9FYXN5KQojI1Bsb3QgSGFyZCB2cy4gRWFzeSBmb3IgU3ViamVjdHMKYGBge3IgZmxpcC1iYXJwbG90NSwgZWNobz1GQUxTRX0KI0RFTEVURSBDcmVhdGUgRGlmZmljdWx0eSBDb2x1bW4KI0RFTEVURSB0b3RhbF9NX2NsZWFuMyRkaWZmaWN1bHR5IDwtIDA7CiNERUxFVEUgdG90YWxfTV9jbGVhbjMkZGlmZmljdWx0eVt0b3RhbF9NX2NsZWFuMyRhYnNTdW1tZWRWYWw8MC41XSA9IDE7CgojQkFSIFBMT1QKI0ZpcnN0IGdldCBtZWFucyBmb3IgZWFjaCBjb25kaXRpb24gb2YgRkxJUCBieSBTdWJqZWN0CmQgPC0gdG90YWxfTV9jbGVhbjMKCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCwgZGlmZmljdWx0eSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShhY2N1cmFjeSA9IG1lYW4oY29ycmVjdCwgbmEucm0gPSBUKSkKCiNQTE9UCmJhcnBsb3QgPC0gZ2dwbG90KHN1YmplY3RfbWVhbnMsIGFlcyh4ID0gZGlmZmljdWx0eSwgeSA9IGFjY3VyYWN5KSkgKwogIHN0YXRfc3VtbWFyeSgKICAgIGdlb20gPSAiYmFyIiwKICAgIGZ1bi55ID0gIm1lYW4iLAogICAgY29sID0gImJsYWNrIiwKICAgIGZpbGwgPSAiZ3JheTcwIgogICkgKwogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaCA9IDAsIHcgPSAwLjIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMS4yKSwKICAgICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYygwLCAwKSkgKwogIGxhYnModGl0bGUgPSAiQWNjdXJhY3kgdnMgRGlmZmljdWx0eSIsIHN1YnRpdGxlID0gIjAuMCA9IGFic29sdXRlIHN1bW1lZCB2YWx1ZSBvZiBpbWFnZXMgPCAkMC41MCAiKQpiYXJwbG90CgojVC5UZXN0IE1lYW5zIG9mIFN1YmplY3RzCnQudGVzdChzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eT09MF0sIHN1YmplY3RfbWVhbnMkYWNjdXJhY3lbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5PT0xXSkKYGBgCgoKIyNQbG90IExPRyBSVCB2cyBBYnNvbHV0ZSBTdW1tZWQgVmFsdWUgCmBgYHtyIHBsb3QtbG9nLXJ0VmFsMywgZWNobz1GQUxTRX0KdG90YWxfTV9jbGVhbjMkYWJzVmFsID0gYWJzKHRvdGFsX01fY2xlYW4zJHN1bW1lZFZhbCkKICAKI1JUIHZzLiBTdW1tZWQgVmFsdWUKZ2dwbG90KHRvdGFsX01fY2xlYW4zLCBhZXMoeD1hYnNWYWwsIHk9bG9nUlQpKSArCiAgZ2VvbV9wb2ludChzaGFwZT0xKSArICAgICMgVXNlIGhvbGxvdyBjaXJjbGVzCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDAsIDMpKSAgKwogIGdlb21fc21vb3RoKCkgICMgQWRkIGEgbG9lc3Mgc21vb3RoZWQgZml0IGN1cnZlIHdpdGggY29uZmlkZW5jZSByZWdpb24KCiNUZXN0IGZvciBTaWcKc3VtbWFyeShsbShsb2dSVH5hYnNWYWwsIHRvdGFsX01fY2xlYW4zKSkKYGBgCgojI1Bsb3QgSW1hZ2UgU3dhcHMgdnMgU3VtbWVkIFZhbHVlIApgYGB7ciBwbG90LXJ0VmFsMywgZWNobz1GQUxTRX0KI3JlbmFtZSBjb2x1bW4gdG8gbWFrZSBtb3JlIGNsZWFyCnRvdGFsX01fY2xlYW4zJHN3YXBDb3VudCA8LSB0b3RhbF9NX2NsZWFuMyRmbGlwQW1vdW50CiNSVCB2cy4gU3VtbWVkIFZhbHVlCmdncGxvdCh0b3RhbF9NX2NsZWFuMywgYWVzKHg9c3VtbWVkVmFsLCB5PXN3YXBDb3VudCkpICsKICBnZW9tX3BvaW50KHNoYXBlPTEpICsgICAgIyBVc2UgaG9sbG93IGNpcmNsZXMKICBnZW9tX3Ntb290aCgpICAjIEFkZCBhIGxvZXNzIHNtb290aGVkIGZpdCBjdXJ2ZSB3aXRoIGNvbmZpZGVuY2UgcmVnaW9uCmBgYAoKCiMjUGxvdCBJbWFnZSBTd2FwcyB2cyBBYnNvbHV0ZSBWYWx1ZSAKYGBge3IgcGxvdC1ydFZhbDQsIGVjaG89RkFMU0V9CiNSVCB2cy4gU3VtbWVkIFZhbHVlCmdncGxvdCh0b3RhbF9NX2NsZWFuMywgYWVzKHg9YWJzU3VtbWVkVmFsLCB5PXN3YXBBbW91bnQpKSArCiAgZ2VvbV9wb2ludChzaGFwZT0xKSAKYGBgCgojI01lYW4gTnVtYmVyIG9mIEZpeGF0aW9ucwpgYGB7ciBwbG90LWZpeGF0aW9uTnVtMDEsIGVjaG89RkFMU0V9CgpkIDwtIHRvdGFsX01fY2xlYW4zCgpzdWJqZWN0X21lYW5zIDwtIGdyb3VwX2J5KGQsIHN1YmplY3QpICU+JQogIGRwbHlyOjpzdW1tYXJpemUoc3dhcEF2ZyA9IG1lYW4oc3dhcEFtb3VudCwgbmEucm0gPSBUKSkKCiNQTE9UCgojTWVhbiBOdW1iZXIgb2YgU3dhcHMKbWVhbihkJHN3YXBBbW91bnQpCgpjb3VudCA9IHNlcSgxLDEzKQpmaXhhdGlvbiA8LSBkYXRhLmZyYW1lKGNvdW50KQoKZm9yKGZpeE51bSBpbiAxOjEzKXsKICBmaXhhdGlvbiRtZWFuc1tmaXhOdW1dIDwtbWVhbih0b3RhbF9NX2NsZWFuM1tbcGFzdGUwKGZpeE51bSwgIl9maXhhdGlvbiIpXV0sIG5hLnJtPVRSVUUpCiAgZml4YXRpb24kc2RbZml4TnVtXSA8LXNkKHRvdGFsX01fY2xlYW4zW1twYXN0ZTAoZml4TnVtLCAiX2ZpeGF0aW9uIildXSwgbmEucm09VFJVRSkKICBmaXhhdGlvbiRjb3VudFtmaXhOdW1dIDwtIGxlbmd0aCh3aGljaCghaXMubmEodG90YWxfTV9jbGVhbjNbW3Bhc3RlMChmaXhOdW0sICJfZml4YXRpb24iKV1dKSkpCn0KCnQudGVzdCh0b3RhbF9NX2NsZWFuMyRgMl9maXhhdGlvbmAsIHRvdGFsX01fY2xlYW4zJGAzX2ZpeGF0aW9uYCwgbmEuYWN0aW9uPW5hLm9taXQpCgojIExhc3QgRml4IFRpbWUKZm9yKHggaW4gMTpsZW5ndGgodG90YWxfTV9jbGVhbjMkVHJpYWwpKXsKICB0b3RhbF9NX2NsZWFuMyRsYXN0Rml4VGltZVt4XSA8LSB0b3RhbF9NX2NsZWFuM1tbcGFzdGUwKHRvdGFsX01fY2xlYW4zJHN3YXBBbW91bnRbeF0sICJfZml4YXRpb24iKV1dW3hdCiAgIyBMYXN0IGltYWdlIHRpbWVzCiAgaWYodG90YWxfTV9jbGVhbjMkbGFzdEltYWdlW3hdID09IDApeyAgICNpZiBsYXN0IGltYWdlID0gMCB0aGVuIGZhY2VWYWwKICAgIHRvdGFsX01fY2xlYW4zJGxhc3RGaXhWYWxbeF0gPSB0b3RhbF9NX2NsZWFuMyRmYWNlVG90YWxbeF0gICAgCiAgfQogIGVsc2V7CiAgICB0b3RhbF9NX2NsZWFuMyRsYXN0Rml4VmFsW3hdID0gdG90YWxfTV9jbGVhbjMkaG91c2VUb3RhbFt4XSAgICAKICB9Cn0KCm1lYW4odG90YWxfTV9jbGVhbjMkbGFzdEltYWdlKQptZWFuKHRvdGFsX01fY2xlYW4zJGxhc3RGaXhWYWwpCm1lYW4odG90YWxfTV9jbGVhbjMkbGFzdEZpeFRpbWUsIG5hLnJtPVQpCgpsZW5ndGgodG90YWxfTV9jbGVhbjMkVHJpYWwpCgojIHN0cmFuZ2VseSwgdHdvIE5BIHZhbHVlcyAoc2VlbSB0byB0aGluayB0aGVyZSB3YXMgYW4gZXh0cmEgc3dhcCkKd2hpY2goaXMubmEodG90YWxfTV9jbGVhbjMkbGFzdEZpeFRpbWUpKQpgYGAKCgojI1N1bW1lZCBWYWx1ZSB2cy4gQWNjZXB0L1JlamVjdCBEZWNpc2lvbgojIyNMb2dpc3RpYyByZWdyZXNzaW9uIGN1cnZlCmBgYHtyIHBsb3QtbmV3LCBlY2hvPUZBTFNFfQojVGhpcyB3YXMgcnVuIHRvIGZpbmQgYSB3ZWlyZCB2YWx1ZSBpbiB0aGUgY29sdW1uCnVuaXF1ZSh0b3RhbF9NX2NsZWFuMyRhY2NlcHRSZWplY3QsIGluY29tcGFyYWJsZXMgPSBGQUxTRSkKdG90YWxfTV9jbGVhbjMkYWNjZXB0UmVqZWN0WzUwNDBdW1sxXV0gPSAwCgojY29udmVydCB0byBkb3VibGUgZnJvbSBMSVNUCnRvdGFsX01fY2xlYW4zJGFjY2VwdFJlamVjdCA8LSBhcy5udW1lcmljKHVubGlzdCh0b3RhbF9NX2NsZWFuMyRhY2NlcHRSZWplY3QpKQoKcGxvdCh0b3RhbF9NX2NsZWFuMyRzdW1tZWRWYWwsIHRvdGFsX01fY2xlYW4zJGFjY2VwdFJlamVjdCkKCm1vZGVsIDwtIGdsbShhY2NlcHRSZWplY3QgfiBzdW1tZWRWYWwsIGRhdGE9dG90YWxfTV9jbGVhbjMsIGZhbWlseT1iaW5vbWlhbChsaW5rID0gbG9naXQpKQpzdW1tYXJ5KG1vZGVsKQoKeHYgPC0gc2VxKG1pbihTX01fcmF3JHN1bW1lZFZhbCksIG1heChTX01fcmF3JHN1bW1lZFZhbCksIDAuMDEpCnl2IDwtIHByZWRpY3QobW9kZWwsbGlzdChzdW1tZWRWYWw9eHYpLCB0eXBlPSJyZXNwb25zZSIpCgpsaW5lcyh4dix5dikKCiNGaW5kIHRoZSBpbmZsZWN0aW9uIHBvaW50IHdoZXJlIHRoZXJlIGlzIGEgNTAvNTAgcHJvYmFiaWxpdHkgb2Ygc3ViamVjdCBhY2NlcHRpbmcuCnAgPC0gMC41CnggPC0gKGxvZyhwLygxLXApKSAtIGNvZWYobW9kZWwpWzFdKSAvIGNvZWYobW9kZWwpWzJdCngKYGBgCgojIyBSVCBDb3JyZWN0IHZzIEluY29ycmVjdCBSZXNwb25zZXMKYGBge3J9CiNHT09EIEJBU0UgRk9SIFBMT1RUSU5HIEVYQU1QTEUKCiNCQVIgUExPVApkIDwtIFNfTQpkJGNvcnJlY3RbZCRjb3JyZWN0PT0xXSA9ICJDb3JyZWN0IgpkJGNvcnJlY3RbZCRjb3JyZWN0PT0wXSA9ICJJbmNvcnJlY3QiCgpzdWJqZWN0X21lYW5zIDwtIGdyb3VwX2J5KGQsIHN1YmplY3QsIGNvcnJlY3QpICU+JQogIGRwbHlyOjpzdW1tYXJpemUocnQgPSBtZWFuKHJ0LCBuYS5ybSA9IFQpKQpzdWJqZWN0X21lYW5zCgojUExPVApiYXJwbG90IDwtIGdncGxvdChzdWJqZWN0X21lYW5zLCBhZXMoeCA9IGNvcnJlY3QsIHkgPSBydCwgZmlsbD1jb3JyZWN0KSkgKwogIHN0YXRfc3VtbWFyeSgKICAgIGdlb20gPSAiYmFyIiwKICAgIGZ1bi55ID0gIm1lYW4iLAogICAgY29sID0gImJsYWNrIiwKICAgIHN0YXQgPSAiaWRlbnRpdHkiCiAgKSArCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoID0gMCwgdyA9IDAuMikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCBtYXgoZCRydCwgbmEucm0gPSBUKSksCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoMCwgMCkpKwogIGxhYnMoeSA9ICJSVCAoc2Vjb25kcykiLCB4ID0gIlJlc3BvbnNlIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsKICBnZ3RpdGxlKCJSVCB2cyBDb3JyZWN0IENob2ljZSIpCgpiYXJwbG90IAp0LnRlc3QoZCRydFtkJGNvcnJlY3Q9PSJDb3JyZWN0Il0sIGQkcnRbZCRjb3JyZWN0PT0iSW5jb3JyZWN0Il0pCmBgYAoKIyMgQmFyUGxvdCBmb3IgQ2hvaWNlIHZzIFJUCmBgYHtyfQojQkFSIFBMT1QKZDwtIFNfTQpkJGNob2ljZVtkJGNob2ljZT09MV0gPSAiQWNjZXB0IgpkJGNob2ljZVtkJGNob2ljZT09MF0gPSAiUmVqZWN0IgoKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShkLCBzdWJqZWN0LCBjaG9pY2UpICU+JQogIGRwbHlyOjpzdW1tYXJpemUocnQgPSBtZWFuKHJ0LCBuYS5ybSA9IFQpKQpzdWJqZWN0X21lYW5zCgojUExPVApiYXJwbG90IDwtIGdncGxvdChzdWJqZWN0X21lYW5zLCBhZXMoeCA9IGNob2ljZSwgeSA9IHJ0LCBmaWxsPWNob2ljZSkpICsKICBzdGF0X3N1bW1hcnkoCiAgICBnZW9tID0gImJhciIsCiAgICBmdW4ueSA9ICJtZWFuIiwKICAgIGNvbCA9ICJibGFjayIsCiAgICBzdGF0ID0gImlkZW50aXR5IgogICkgKwogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaCA9IDAsIHcgPSAwLjIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgbWF4KGQkcnQsIG5hLnJtID0gVCkpLAogICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKDAsIDApKSsKICBsYWJzKHkgPSAiUlQgKHNlY29uZHMpIiwgeCA9ICJSZXNwb25zZSIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsKICBnZ3RpdGxlKCJSVCB2cyBDaG9pY2UiKQogICNzdGF0X2NvbXBhcmVfbWVhbnMobGFiZWwueSA9IDguMCkgKwogICNzdGF0X2NvbXBhcmVfbWVhbnMocmVmLmdyb3VwID0gIkFjY2VwdCIsIGxhYmVsID0gInAuc2lnbmlmIiwgbGFiZWwueSA9IGMoNy4wKSkKCmJhcnBsb3QgCgp0LnRlc3QoZCRydFtkJGNob2ljZT09IkFjY2VwdCJdLCBkJHJ0W2QkY2hvaWNlPT0iUmVqZWN0Il0pCmBgYAoKIyMgRGVjaWRpbmcgRmFjdG9yOiBIb3VzZS9GYWNlCgpgYGB7cn0KI0JBUiBQTE9UCmQ8LSBTX00KIyBSZWR1Y2UgREYgdG8gRGVjaWRlciBUcmlhbHMKeDwtIChkJGZhY2VUb3RhbD4wICYgZCRob3VzZVRvdGFsPDApIHwgKGQkZmFjZVRvdGFsPDAgJiBkJGhvdXNlVG90YWw+MCkKZCA9IGRbeD09VFJVRSxdCiMgQ3JlYXRlIERlY2lkZXIgQ29sdW1uCmQkZGVjaWRlciA9IDAKZCRkZWNpZGVyW2FicyhkJGZhY2VUb3RhbCk+YWJzKGQkaG91c2VUb3RhbCldID0gIkZhY2UiCmQkZGVjaWRlclthYnMoZCRob3VzZVRvdGFsKT5hYnMoZCRmYWNlVG90YWwpXSA9ICJIb3VzZSIKI3JlbW92ZSB2YWx1ZXMgb2YgemVybwpkID0gZFtkJGRlY2lkZXIhPTAsXQoKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShkLCBzdWJqZWN0LCBkZWNpZGVyKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHJ0ID0gbWVhbihydCwgbmEucm0gPSBUKSkKc3ViamVjdF9tZWFucwoKI1BMT1QKYmFycGxvdCA8LSBnZ3Bsb3Qoc3ViamVjdF9tZWFucywgYWVzKHggPSBkZWNpZGVyLCB5ID0gcnQsIGZpbGw9ZGVjaWRlcikpICsKICBzdGF0X3N1bW1hcnkoCiAgICBnZW9tID0gImJhciIsCiAgICBmdW4ueSA9ICJtZWFuIiwKICAgIGNvbCA9ICJibGFjayIsCiAgICBzdGF0ID0gImlkZW50aXR5IgogICkgKwogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaCA9IDAsIHcgPSAwLjIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgbWF4KGQkcnQsIG5hLnJtID0gVCkpLAogICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKDAsIDApKSsKICBsYWJzKHkgPSAiUlQgKHNlY29uZHMpIiwgeCA9ICJSZXNwb25zZSIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsKICBnZ3RpdGxlKCJSVCB2cyBEZWNpZGVyIFN0aW11bHVzIikKICAjc3RhdF9jb21wYXJlX21lYW5zKGxhYmVsLnkgPSA4LjApICsKICAjc3RhdF9jb21wYXJlX21lYW5zKHJlZi5ncm91cCA9ICJBY2NlcHQiLCBsYWJlbCA9ICJwLnNpZ25pZiIsIGxhYmVsLnkgPSBjKDcuMCkpCgpiYXJwbG90IAoKdC50ZXN0KGQkcnRbZCRkZWNpZGVyPT0iRmFjZSJdLCBkJHJ0W2QkZGVjaWRlcj09IkhvdXNlIl0pCmBgYAoKIyMgQWNjdXJhY3kgdnMgTmVnL1BvcyBTdW1tZWQgVmFsdWUKCmBgYHtyfQojQkFSIFBMT1QKZDwtIFNfTQojIFJlZHVjZSBERiB0byBEZWNpZGVyIFRyaWFscwpkJHBvc05lZyA8LSAwCmQkcG9zTmVnW2Qkc3VtbWVkVmFsPjBdID0gIlBvc2l0aXZlIgpkJHBvc05lZ1tkJHN1bW1lZFZhbDwwXSA9ICJOZWdhdGl2ZSIKZCA8LSBkW2Qkc3VtbWVkVmFsIT0wLF0gIyByZW1vdmUgdmFsdWVzIG9mIDAKCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCwgcG9zTmVnKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGFjY3VyYWN5ID0gbWVhbihjb3JyZWN0LCBuYS5ybSA9IFQpKQpzdWJqZWN0X21lYW5zCnN1YmplY3RfbWVhbnMkbWVhbkFjYyA9IG1lYW4oc3ViamVjdF9tZWFucyRhY2N1cmFjeSkKCiNQTE9UCmJhcnBsb3QgPC0gZ2dwbG90KHN1YmplY3RfbWVhbnMsIGFlcyh4ID0gcG9zTmVnLCB5ID0gYWNjdXJhY3ksIGZpbGw9cG9zTmVnLCBsYWJlbD1hY2N1cmFjeSkpICsKICBzdGF0X3N1bW1hcnkoCiAgICBnZW9tID0gImJhciIsCiAgICBmdW4ueSA9ICJtZWFuIiwKICAgIGNvbCA9ICJibGFjayIsCiAgICBzdGF0ID0gImlkZW50aXR5IgogICkgKwogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaCA9IDAsIHcgPSAwLjIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgbWF4KGQkYWNjdXJhY3krMC4yNSwgbmEucm0gPSBUKSksCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoMCwgMCkpKwogIGxhYnMoeSA9ICJBY2N1cmFjeSIsIHggPSAiU3VtbWVkIFZhbHVlIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGdndGl0bGUoIkFjY3VyYWN5IHZzIFN1bW1lZCBWYWx1ZSBTaWduIikKICAjc3RhdF9jb21wYXJlX21lYW5zKGxhYmVsLnkgPSA4LjApICsKICAjc3RhdF9jb21wYXJlX21lYW5zKHJlZi5ncm91cCA9ICJBY2NlcHQiLCBsYWJlbCA9ICJwLnNpZ25pZiIsIGxhYmVsLnkgPSBjKDcuMCkpCgpiYXJwbG90IAoKdC50ZXN0KGQkY29ycmVjdFtkJHBvc05lZz09IlBvc2l0aXZlIl0sIGQkY29ycmVjdFtkJHBvc05lZz09Ik5lZ2F0aXZlIl0pCmBgYAoKIyMgUlQgdnMgUG9zaXRpdmUvTmVnYXRpdmUgU3VtbWVkIFZhbHVlCgpgYGB7cn0KI0JBUiBQTE9UCmQ8LSBTX00KIyBSZWR1Y2UgREYgdG8gRGVjaWRlciBUcmlhbHMKZCRwb3NOZWcgPC0gMApkJHBvc05lZ1tkJHN1bW1lZFZhbD4wXSA9ICJQb3NpdGl2ZSIKZCRwb3NOZWdbZCRzdW1tZWRWYWw8MF0gPSAiTmVnYXRpdmUiCmQgPC0gZFtkJHN1bW1lZFZhbCE9MCxdICMgcmVtb3ZlIHZhbHVlcyBvZiAwCgpzdWJqZWN0X21lYW5zIDwtIGdyb3VwX2J5KGQsIHN1YmplY3QsIHBvc05lZykgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShydCA9IG1lYW4ocnQsIG5hLnJtID0gVCkpCnN1YmplY3RfbWVhbnMKCiNQTE9UCmJhcnBsb3QgPC0gZ2dwbG90KHN1YmplY3RfbWVhbnMsIGFlcyh4ID0gcG9zTmVnLCB5ID0gcnQsIGZpbGw9cG9zTmVnKSkgKwogIHN0YXRfc3VtbWFyeSgKICAgIGdlb20gPSAiYmFyIiwKICAgIGZ1bi55ID0gIm1lYW4iLAogICAgY29sID0gImJsYWNrIiwKICAgIHN0YXQgPSAiaWRlbnRpdHkiCiAgKSArCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoID0gMCwgdyA9IDAuMikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCBtYXgoZCRydC0yLjUsIG5hLnJtID0gVCkpLAogICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKDAsIDApKSsKICBsYWJzKHkgPSAiUlQgKHNlY29uZHMpIiwgeCA9ICJTdW1tZWQgVmFsdWUiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZSgiUlQgdnMgU3VtbWVkIFZhbHVlIFNpZ24iKQogICNzdGF0X2NvbXBhcmVfbWVhbnMobGFiZWwueSA9IDguMCkgKwogICNzdGF0X2NvbXBhcmVfbWVhbnMocmVmLmdyb3VwID0gIkFjY2VwdCIsIGxhYmVsID0gInAuc2lnbmlmIiwgbGFiZWwueSA9IGMoNy4wKSkKCmJhcnBsb3QgCgp0LnRlc3QoZCRydFtkJHBvc05lZz09IlBvc2l0aXZlIl0sIGQkcnRbZCRwb3NOZWc9PSJOZWdhdGl2ZSJdKQpgYGAKCiMjIEZpcnN0L01pZGRsZS9MYXN0IEZpeGF0aW9uIG1lYW4gZHVyYXRpb24gKGJveFBsb3QpCgpgYGB7cn0KbG9hZCgiL1VzZXJzL2Rqdy9Ecm9wYm94L1BST0dSQU1NSU5HLypORVVSTy9hRERNX0tyYWpiaWNoL1NfTV9LLlJkYXRhIikKZCA8LSBTX01fSwoKZCRmaXhUeXBlIDwtIDIKZCRmaXhUeXBlW2QkZml4TnVtPT0xXSA8LSAxCmQkZml4VHlwZVtkJHJldkZpeE51bT09MV0gPC0zCgptZWRpYW4oZCRmaXhEdXJbZCRmaXhUeXBlPT0xXSkKbWVkaWFuKGQkZml4RHVyW2QkZml4VHlwZT09Ml0pCm1lZGlhbihkJGZpeER1cltkJGZpeFR5cGU9PTNdKQoKCm15X2NvbXBhcmlzb25zIDwtIGxpc3QoIGMoIjEiLCAiMiIpLCBjKCIxIiwgIjMiKSwgYygiMiIsICIzIikgKQoKcDAgPSBnZ2JveHBsb3QoZCwgeCA9ICJmaXhUeXBlIiwgeSA9ICJmaXhEdXIiLCBjb2xvciA9ICJmaXhUeXBlIiwgcGFsZXR0ZSA9ICJqY28iICkrICNvdXRsaWVyLnNoYXBlPU5BCiAgCiAgbGFicyh5ID0gIkZpeGF0aW9uIFRpbWUgKHNlY29uZHMpIiwgeCA9ICJGaXhhdGlvbiBUeXBlIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsgIAogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIjEiID0gIkZpcnN0IiwgIjIiID0gIk1pZGRsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIzIiA9ICJMYXN0IikpICsKICAjc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IHF1YW50aWxlKGQkZml4RHVyLCBjKDAuMSwgMC45KSkpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucykrICMgQWRkIHBhaXJ3aXNlIGNvbXBhcmlzb25zIHAtdmFsdWUKICBzdGF0X2NvbXBhcmVfbWVhbnMobGFiZWwueSA9IDEzKSArICAgICAjIEFkZCBnbG9iYWwgcC12YWx1ZQogIGdndGl0bGUoIkZpeGF0aW9uIER1cmF0aW9ucyIpCgpwMAoKIyMgSG93IG1hbnkgdHJpYWxzIHdpdGggbW9yZSB0aGFuIDIgZml4YXRpbm9zCmQgPSBTX00KbGVuZ3RoKGQkVHJpYWxbZCRzd2FwQW1vdW50PjJdKS9sZW5ndGgoZCRUcmlhbCkKCm1lYW4oZCRmaXJzdFZhbFtkJHN3YXBBbW91bnQ8Ml0pCmBgYAoKIyMgU3VtbWVkIFZhbCB2cyBGaXhhdGlvbnMKCmBgYHtyfQpkZiA8LSBTX00KCiNSVCB2cy4gU3VtbWVkIFZhbHVlCmdncGxvdCgpICsKICBnZW9tX3Ntb290aChhZXMoeD1zdW1tZWRWYWwsIHk9c3dhcEFtb3VudCksIGRmKSArCiAgI2dlb21fc21vb3RoKGFlcyh4PXN1bW1lZFZhbCwgeT1sb2dSVCwgY29sb3VyID0gImZsaXAiKSwgc3Vic2V0KHRvdGFsX01fY2xlYW4zLCBmbGlwPT0xKSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMywgMykpICArCiAgZ2d0aXRsZSgiU3VtbWVkIFZhbHVlIHZzIEZpeGF0aW9ucyIpCiAgI2dlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkgICMgQWRkIGEgbG9lc3Mgc21vb3RoZWQgZml0IGN1cnZlIHdpdGggY29uZmlkZW5jZSByZWdpb24KCiNUZXN0IGZvciBTSUcKc3VtbWFyeShsbShgMl9maXhhdGlvbmB+c3VtbWVkVmFsICsgZmFjdG9yKHNlY29uZE11bHQpLCBkZikpCmBgYAoKCmBgYHtyfQojIGNyZWF0ZSBhIGR1bW15IGRhdGEgZnJhbWUgd2l0aCBvdXRsaWVycwpkZiA9IGRhdGEuZnJhbWUoeSA9IGMoLTEwMCwgcm5vcm0oMTAwKSwgMTAwKSkKCiMgY3JlYXRlIGJveHBsb3QgdGhhdCBpbmNsdWRlcyBvdXRsaWVycwpwMCA9IGdncGxvdChkZiwgYWVzKHkgPSB5KSkgKyBnZW9tX2JveHBsb3QoYWVzKHggPSBmYWN0b3IoMSkpKQoKcDAKIyBjb21wdXRlIGxvd2VyIGFuZCB1cHBlciB3aGlza2Vycwp5bGltMSA9IGJveHBsb3Quc3RhdHMoZGYkeSkkc3RhdHNbYygxLCA1KV0KCiMgc2NhbGUgeSBsaW1pdHMgYmFzZWQgb24geWxpbTEKcDEgPSBwMCArIGNvb3JkX2NhcnRlc2lhbih5bGltID0geWxpbTEqMS4wNSkKcDEKYGBgCgoKIyNQbG90IFJUIHdpdGgvd2l0aG91dCBGbGlwCmBgYHtyIGZsaXAtYmFycGxvdDIsIGVjaG89RkFMU0V9CgojQkFSIFBMT1QKI0ZpcnN0IGdldCBtZWFucyBmb3IgZWFjaCBjb25kaXRpb24gb2YgRkxJUCBieSBTdWJqZWN0CmQgPC0gU19NCgpkJGZsaXAgPC0gZmFjdG9yKGQkZmxpcCkKCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCwgZmxpcCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShydCA9IG1lYW4ocnQsIG5hLnJtID0gVCkpCgpjb2xsYXBzZWREYXRhID0gZGF0YS5mcmFtZSgiVHJpYWwiID0gYygxLDIpLCAiTWVhbiIgPSAwLCAiU0UiID0gMCkKY29sbGFwc2VkRGF0YSRNZWFuW2NvbGxhcHNlZERhdGEkVHJpYWwgPT0gMV0gPSBtZWFuKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRmbGlwID09IDFdKQpjb2xsYXBzZWREYXRhJE1lYW5bY29sbGFwc2VkRGF0YSRUcmlhbCA9PSAyXSA9IG1lYW4oc3ViamVjdF9tZWFucyRydFtzdWJqZWN0X21lYW5zJGZsaXAgPT0gMl0pCmNvbGxhcHNlZERhdGEkU0VbY29sbGFwc2VkRGF0YSRUcmlhbCA9PSAxXSA9IHNkKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRmbGlwID09IDFdKS9zcXJ0KGxlbmd0aCh1bmlxdWUoc3ViamVjdF9tZWFucyRzdWJqZWN0KSkpCmNvbGxhcHNlZERhdGEkU0VbY29sbGFwc2VkRGF0YSRUcmlhbCA9PSAyXSA9IHNkKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRmbGlwID09IDJdKS9zcXJ0KGxlbmd0aCh1bmlxdWUoc3ViamVjdF9tZWFucyRzdWJqZWN0KSkpCgojUExPVApiYXJwbG90IDwtIGdncGxvdChzdWJqZWN0X21lYW5zLCBhZXMoeCA9IGZsaXAsIHkgPSBydCwgZmlsbD1mbGlwKSkgKwogIHN0YXRfc3VtbWFyeSgKICAgIGdlb20gPSAiYmFyIiwKICAgIGZ1bi55ID0gIm1lYW4iCiAgKSArCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoID0gMCwgdyA9IDAuMikpICsKICBsYWJzKHkgPSAiUmVhY3Rpb24gVGltZSAoc2Vjb25kcykiLCB4ID0gIlRyaWFsIFR5cGUiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiMSIgPSAiUmV2ZXJzYWwiLCAiMiIgPSAiTm9uLVJldmVyc2FsIikpICsgIAogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIG1heChkJHJ0LCBuYS5ybSA9IFQpIC0gMyksCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoMCwgMCkpICsgCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQpiYXJwbG90CgojIERPbid0IHBsb3QgaW5kaXZpZHVkYWwgc3ViamVjdCwgYWRkIFNFIGJhcnMKCmNvbGxhcHNlZERhdGEkVHJpYWwgPC0gZmFjdG9yKGNvbGxhcHNlZERhdGEkVHJpYWwpCnA8LSBnZ3Bsb3QoY29sbGFwc2VkRGF0YSwgYWVzKHg9VHJpYWwsIHk9TWVhbiwgZmlsbD1UcmlhbCkpICsgCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBjb2xvcj0iYmxhY2siLCAKICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1NZWFuLVNFLCB5bWF4PU1lYW4rU0UpLCB3aWR0aD0uMiwKICAgICAgICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsKICBsYWJzKHkgPSAiUmVhY3Rpb24gVGltZSAocykiLCB4ID0gIlRyaWFsIFR5cGUiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiMSIgPSAiUmV2ZXJzYWwiLCAiMiIgPSAiTm9uLVJldmVyc2FsIikpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDIuMiwgMy41KSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKcApgYGAKCiMjVCBUZXN0IG9uIFJUIGRpZmZlcmVuY2UgYmV0d2VlbiBmbGlwIGFuZCBub24gZmxpcCB0cmlhbHMgUlQKYGBge3IgdC10ZXN0LCBlY2hvPVRSVUV9CmxpYnJhcnkodGlkeXIpCnN1YmplY3RfbWVhbnNfd2lkZSA8LQogIHNwcmVhZChzdWJqZWN0X21lYW5zLAogICAgICAgICBrZXkgPSBmbGlwLAogICAgICAgICB2YWx1ZSA9IHJ0LAogICAgICAgICBzZXAgPSAiXyIpCnN1YmplY3RfbWVhbnNfd2lkZQoKI1QtVEVTVCBmb3IgZmxpcCB2cy4gbm9uLWZsaXAgdHJpYWxzCnQudGVzdChzdWJqZWN0X21lYW5zX3dpZGUkZmxpcF8xLCBzdWJqZWN0X21lYW5zX3dpZGUkZmxpcF8yLCBwYWlyZWQgPSBUUlVFKQptZWFuKHN1YmplY3RfbWVhbnNfd2lkZSRmbGlwXzIpCnNkKHN1YmplY3RfbWVhbnNfd2lkZSRmbGlwXzIpCmBgYAoKIyNQbG90IHBlcmZvcm1hbmNlIHdpdGgvd2l0aG91dCBGbGlwCmBgYHtyIGZsaXAtYmFycGxvdCwgZWNobz1GQUxTRX0KCiNCQVIgUExPVAojRmlyc3QgZ2V0IG1lYW5zIGZvciBlYWNoIGNvbmRpdGlvbiBvZiBGTElQIGJ5IFN1YmplY3QKZCA8LSBTX00KCmQkZmxpcCA8LSBmYWN0b3IoZCRmbGlwKQoKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShkLCBzdWJqZWN0LCBmbGlwKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGNvclBjdCA9IG1lYW4oY29ycmVjdCwgbmEucm0gPSBUKSkKCmNvbGxhcHNlZERhdGEgPSBkYXRhLmZyYW1lKCJUcmlhbCIgPSBjKDEsMiksICJNZWFuIiA9IDAsICJTRSIgPSAwKQpjb2xsYXBzZWREYXRhJE1lYW5bY29sbGFwc2VkRGF0YSRUcmlhbCA9PSAxXSA9IG1lYW4oc3ViamVjdF9tZWFucyRjb3JQY3Rbc3ViamVjdF9tZWFucyRmbGlwID09IDFdKQpjb2xsYXBzZWREYXRhJE1lYW5bY29sbGFwc2VkRGF0YSRUcmlhbCA9PSAyXSA9IG1lYW4oc3ViamVjdF9tZWFucyRjb3JQY3Rbc3ViamVjdF9tZWFucyRmbGlwID09IDJdKQpjb2xsYXBzZWREYXRhJFNFW2NvbGxhcHNlZERhdGEkVHJpYWwgPT0gMV0gPSBzZChzdWJqZWN0X21lYW5zJGNvclBjdFtzdWJqZWN0X21lYW5zJGZsaXAgPT0gMV0pL3NxcnQobGVuZ3RoKHVuaXF1ZShzdWJqZWN0X21lYW5zJHN1YmplY3QpKSkKY29sbGFwc2VkRGF0YSRTRVtjb2xsYXBzZWREYXRhJFRyaWFsID09IDJdID0gc2Qoc3ViamVjdF9tZWFucyRjb3JQY3Rbc3ViamVjdF9tZWFucyRmbGlwID09IDJdKS9zcXJ0KGxlbmd0aCh1bmlxdWUoc3ViamVjdF9tZWFucyRzdWJqZWN0KSkpCgojUExPVApiYXJwbG90IDwtIGdncGxvdChzdWJqZWN0X21lYW5zLCBhZXMoeCA9IGZsaXAsIHkgPSBjb3JQY3QsIGZpbGwgPSBmbGlwKSkgKwogIHN0YXRfc3VtbWFyeSgKICAgIGdlb20gPSAiYmFyIiwKICAgIGZ1bi55ID0gIm1lYW4iCiAgKSArCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoID0gMCwgdyA9IDAuMikpICsKICBsYWJzKHkgPSAicChDb3JyZWN0KSIsIHggPSAiVHJpYWwgVHlwZSIpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIxIiA9ICJSZXZlcnNhbCIsICIyIiA9ICJOb24tUmV2ZXJzYWwiKSkgKyAgCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgbWF4KGQkY29ycmVjdCwgbmEucm0gPSBUKSsuMSksCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoMCwgMCkpKwogIHRoZW1lX21pbmltYWwoKSArCiAgI2dlb21fZXJyb3JiYXIoYWVzKHltaW49Y29yUGN0LXNkKGNvclBjdCksIHltYXg9Y29yUGN0K3NkKGNvclBjdCkpLCB3aWR0aD0uMSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmJhcnBsb3QKCmNvbGxhcHNlZERhdGEkVHJpYWwgPC0gZmFjdG9yKGNvbGxhcHNlZERhdGEkVHJpYWwpCnA8LSBnZ3Bsb3QoY29sbGFwc2VkRGF0YSwgYWVzKHg9VHJpYWwsIHk9TWVhbiwgZmlsbD1UcmlhbCkpICsgCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBjb2xvcj0iYmxhY2siLCAKICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1NZWFuLVNFLCB5bWF4PU1lYW4rU0UpLCB3aWR0aD0uMiwKICAgICAgICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsKICBsYWJzKHkgPSAicChDb3JyZWN0KSIsIHggPSAiVHJpYWwgVHlwZSIpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIxIiA9ICJSZXZlcnNhbCIsICIyIiA9ICJOb24tUmV2ZXJzYWwiKSkgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltPWMoMC43NywgMC44OCkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCnAKYGBgCgpCYXNlZCBvbiB0aGUgcGxvdCBpdCBsb29rcyBsaWtlIGZsaXAgdHJpYWxzIG9uIGF2ZXJhZ2UgZG8gKldPUlNFKiBhbmQgaGF2ZSBoaWdoZXIgKlZBUklBTkNFKiBiZXR3ZWVuIHN1YmplY3RzIChpbiBhZGRpdGlvbiB0byB0YWtpbmcgbG9uZ2VyKQoKIyNUIFRlc3Qgb24gUlQgZGlmZmVyZW5jZSBiZXR3ZWVuIGZsaXAgYW5kIG5vbiBmbGlwIHRyaWFscyAlIENvcnJlY3QKYGBge3IgdC10ZXN0MiwgZWNobz1UUlVFfQpzdWJqZWN0X21lYW5zX3dpZGUgPC0KICBzcHJlYWQoc3ViamVjdF9tZWFucywKICAgICAgICAga2V5ID0gZmxpcCwKICAgICAgICAgdmFsdWUgPSBjb3JQY3QsCiAgICAgICAgIHNlcCA9ICJfIikKc3ViamVjdF9tZWFuc193aWRlCgojVC1URVNUIGZvciBmbGlwIHZzLiBub24tZmxpcCB0cmlhbHMKdC50ZXN0KHN1YmplY3RfbWVhbnNfd2lkZSRmbGlwXzEsIHN1YmplY3RfbWVhbnNfd2lkZSRmbGlwXzIsIHBhaXJlZCA9IFRSVUUpCnNkKHN1YmplY3RfbWVhbnNfd2lkZSRmbGlwXzIpCmBgYAoKSXQgdHVybnMgb3V0IHRoYXQgdGhlIGRpZmZlcmVuY2UgaW4gcGVyZm9ybWFuY2UgaXMgKm5vdCogc2lnbmlmaWNhbnQuCgoKCiMjUGxvdCBSVCB2cyBuZWdhdGl2ZS9wb3NpdGl2ZSBzdW1tZWQgVmFsCmBgYHtyIHBvc05lZy1iYXJwbG90MiwgZWNobz1GQUxTRX0KCiNCQVIgUExPVAojRmlyc3QgZ2V0IG1lYW5zIGZvciBlYWNoIGNvbmRpdGlvbiBvZiBGTElQIGJ5IFN1YmplY3QKZCA8LSB0b3RhbF9NX2NsZWFuMwoKZCRwb3NOZWdTdW0gPC0gMApkJHBvc05lZ1N1bVtkJHN1bW1lZFZhbD4wXSA8LSAxCgpzdWJqZWN0X21lYW5zIDwtIGdyb3VwX2J5KGQsIHN1YmplY3QsIHBvc05lZ1N1bSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShydCA9IG1lYW4oUlQsIG5hLnJtID0gVCkpCnN1YmplY3RfbWVhbnMKCiNQTE9UCmJhcnBsb3QgPC0gZ2dwbG90KHN1YmplY3RfbWVhbnMsIGFlcyh4ID0gcG9zTmVnU3VtLCB5ID0gcnQpKSArCiAgc3RhdF9zdW1tYXJ5KAogICAgZ2VvbSA9ICJiYXIiLAogICAgZnVuLnkgPSAibWVhbiIsCiAgICBjb2wgPSAiYmxhY2siLAogICAgZmlsbCA9ICJncmF5NzAiCiAgKSArCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoID0gMCwgdyA9IDAuMikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCBtYXgoZCRSVCwgbmEucm0gPSBUKSksCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoMCwgMCkpCmJhcnBsb3QKYGBgCgpCYXNlZCBvbiB0aGUgcGxvdCBpdCBsb29rcyBsaWtlIFJUIGlzICpsb25nZXIqIGZvciBuZWdhdGl2ZSBzdW1tZWQgdmFsdWVzLgoKIyNUIFRlc3Qgb24gUlQgZGlmZmVyZW5jZSBiZXR3ZWVuIHBvcy9uZWcgc3VtbWVkIHZhbHVlcwpgYGB7ciB0LXRlc3Q0LCBlY2hvPVRSVUV9CnN1YmplY3RfbWVhbnNfd2lkZSA8LQogIHNwcmVhZChzdWJqZWN0X21lYW5zLAogICAgICAgICBrZXkgPSBwb3NOZWdTdW0sCiAgICAgICAgIHZhbHVlID0gcnQsCiAgICAgICAgIHNlcCA9ICJfIikKCiNULVRFU1QgZm9yIGZsaXAgdnMuIG5vbi1mbGlwIHRyaWFscwp0LnRlc3Qoc3ViamVjdF9tZWFuc193aWRlJHBvc05lZ1N1bV8wLCBzdWJqZWN0X21lYW5zX3dpZGUkcG9zTmVnU3VtXzEsIHBhaXJlZCA9IFRSVUUpCmBgYAoKVGhpcyBzdWdnZXN0cyB0aGF0IHRoZXJlIGlzIGEgc2lnbmlmaWNhbnRseSBsb25nZXIgdGltZSBzcGVudCBvbiBjaG9pY2VzIHdpdGggYSBuZWdhdGl2ZSBzdW1tZWQgdmFsdWUuCgoKIyNQbG90ICUgQ29ycmVjdCB2cyBuZWdhdGl2ZS9wb3NpdGl2ZSBzdW1tZWQgVmFsCmBgYHtyIHBvc05lZy1iYXJwbG90LCBlY2hvPUZBTFNFfQoKI0JBUiBQTE9UCiNGaXJzdCBnZXQgbWVhbnMgZm9yIGVhY2ggY29uZGl0aW9uIG9mIEZMSVAgYnkgU3ViamVjdApkIDwtIHRvdGFsX01fY2xlYW4zCgpkJHBvc05lZ1N1bSA8LSAwCmQkcG9zTmVnU3VtW2Qkc3VtbWVkVmFsPjBdIDwtIDEKCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCwgcG9zTmVnU3VtKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGNvclBjdCA9IG1lYW4oY29ycmVjdCwgbmEucm0gPSBUKSkKCiNQTE9UCmJhcnBsb3QgPC0gZ2dwbG90KHN1YmplY3RfbWVhbnMsIGFlcyh4ID0gcG9zTmVnU3VtLCB5ID0gY29yUGN0KSkgKwogIHN0YXRfc3VtbWFyeSgKICAgIGdlb20gPSAiYmFyIiwKICAgIGZ1bi55ID0gIm1lYW4iLAogICAgY29sID0gImJsYWNrIiwKICAgIGZpbGwgPSAiZ3JheTcwIgogICkgKwogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaCA9IDAsIHcgPSAwLjIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgbWF4KGQkY29ycmVjdCwgbmEucm0gPSBUKSksCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoMCwgMCkpCmJhcnBsb3QKYGBgCgpCYXNlZCBvbiB0aGUgcGxvdCBpdCBsb29rcyBsaWtlIHBlb3BsZSBkbyAqYmV0dGVyKiB3aGVuIHRoZSBzdW1tZWQgdmFsIGlzIHBvc2l0aXZlLgoKIyNUIFRlc3Qgb24gUlQgZGlmZmVyZW5jZSBiZXR3ZWVuIGZsaXAgYW5kIG5vbiBmbGlwIHRyaWFscyAlIENvcnJlY3QKYGBge3IgdC10ZXN0MywgZWNobz1UUlVFfQpzdWJqZWN0X21lYW5zX3dpZGUgPC0KICBzcHJlYWQoc3ViamVjdF9tZWFucywKICAgICAgICAga2V5ID0gcG9zTmVnU3VtLAogICAgICAgICB2YWx1ZSA9IGNvclBjdCwKICAgICAgICAgc2VwID0gIl8iKQpzdWJqZWN0X21lYW5zX3dpZGUKCiNULVRFU1QgZm9yIGZsaXAgdnMuIG5vbi1mbGlwIHRyaWFscwp0LnRlc3Qoc3ViamVjdF9tZWFuc193aWRlJHBvc05lZ1N1bV8wLCBzdWJqZWN0X21lYW5zX3dpZGUkcG9zTmVnU3VtXzEsIHBhaXJlZCA9IFRSVUUpCmBgYAoKVGhlIGRpZmZlcmVuY2UgaXMgc2lnbmlmaWNhbnQuIFNvIHBlb3BsZSB0YWtlIGxlc3MgdGltZSBidXQgcGVyZm9ybSBiZXR0ZXIgd2hlbiB0aGUgc3VtbWVkIHZhbHVlIGlzIHBvc2l0aXZlLgoKIyMgTXVsdGlwbGllcnMgYW5kIEFic29sdXRlIE5ldCBWYWx1ZQoKYGBge3J9CmQgPC0gU19NCgojIEVGRkVDVFMgb24gQWJzIFZhbCBkdWUgdG8gTVVMVFMKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShkLCBzdWJqZWN0LCBtdWx0TnVtKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGFic05ldCA9IG1lYW4oYWJzU3VtbWVkVmFsLCBuYS5ybSA9IFQpLCBydCA9IG1lYW4ocnQsIG5hLnJtID0gVCkpCnN1YmplY3RfbWVhbnMKCiMgTWVhbiBieSBNdWx0Cm1lYW4oc3ViamVjdF9tZWFucyRhYnNOZXRbc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDBdKQptZWFuKHN1YmplY3RfbWVhbnMkYWJzTmV0W3N1YmplY3RfbWVhbnMkbXVsdE51bSA9PSAxXSkKbWVhbihzdWJqZWN0X21lYW5zJGFic05ldFtzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMl0pCgojIFNEIGJ5IE11bHQKc2Qoc3ViamVjdF9tZWFucyRhYnNOZXRbc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDBdKQpzZChzdWJqZWN0X21lYW5zJGFic05ldFtzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMV0pCnNkKHN1YmplY3RfbWVhbnMkYWJzTmV0W3N1YmplY3RfbWVhbnMkbXVsdE51bSA9PSAyXSkKCiMgMCAxCnQudGVzdChzdWJqZWN0X21lYW5zJGFic05ldFtzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJqZWN0X21lYW5zJGFic05ldFtzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMV0sIHBhaXJlZCA9IFRSVUUpCiMgMSAyCnQudGVzdChzdWJqZWN0X21lYW5zJGFic05ldFtzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJqZWN0X21lYW5zJGFic05ldFtzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMl0sIHBhaXJlZCA9IFRSVUUpCiMgMCAyCnQudGVzdChzdWJqZWN0X21lYW5zJGFic05ldFtzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMF0sCiAgICAgICBzdWJqZWN0X21lYW5zJGFic05ldFtzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMl0sIHBhaXJlZCA9IFRSVUUpCgpgYGAKCgojIyBSVCBkaXN0cmlidXRpb25zIGZvciBkaWZmZXJlbnQgbXVsdE51bXMKCmBgYHtyfQpkID0gU19NCgptZWQuZmFjID0gZGRwbHkoZCwgLihtdWx0TnVtKSwgZnVuY3Rpb24oLmQpCmRhdGEuZnJhbWUoeD1tZWRpYW4oLmQkcnQpKSkKCiMgSElTVE9HUkFNIFZFUlNJT04KcCA8LSBnZ3Bsb3QoZGF0YSA9IGQsIGFlcyh4ID0gcnQsIGZpbGw9bXVsdE51bSkpICsgCiAgZ2VvbV9oaXN0b2dyYW0oKSArCiAgbGFicyh0aXRsZT0iUlQgRGlzdHJpYnV0aW9uIHZzLiBOdW1iZXIgb2YgTXVsdGlwbGllcnMiLCB4ID0gIlJUIChzZWNvbmRzKSIsIHkgPSJDb3VudCIpICsKICBnZW9tX3ZsaW5lKGRhdGE9bWVkLmZhYywgYWVzKHhpbnRlcmNlcHQ9eCkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCnAgKyBmYWNldF93cmFwKH5tdWx0TnVtKQoKIyBCT1hQTE9UIFZFUlNJT04KCiMgY3JlYXRlIG1lZGlhbnMgdG8gaW5zZXJ0IGFzIHRleHQKeCA8LSBkCngkbXVsdE51bSA9IGQkbXVsdE51bSsxCnBfbWVkcyA8LSBkZHBseSh4LCAuKG11bHROdW0pLCBzdW1tYXJpc2UsIG1lZCA9IG1lZGlhbihydCkpCnBfbWVkcyRtZWQgPSByb3VuZChwX21lZHMkbWVkLCBkaWdpdHMgPSAyKSAgIyByb3VuZCB0byB0d28gZGVjaW1hbCB2YWx1ZXMKCiMgTGlzdCBvZiBjb25kaXRpb25zIHRvIGNvbXBhcmUKbXlfY29tcGFyaXNvbnMgPC0gbGlzdCggYygiMCIsICIxIiksIGMoIjAiLCAiMiIpLCBjKCIxIiwgIjIiKSApCgpwMCA9IGdnYm94cGxvdChkLCB4ID0gIm11bHROdW0iLCB5ID0gInJ0IiwgY29sb3IgPSAibXVsdE51bSIsIHBhbGV0dGUgPSAiamNvIiApKyAjb3V0bGllci5zaGFwZT1OQQogIAogIGxhYnMoeSA9ICJUb3RhbCBSVCAoc2Vjb25kcykiLCB4ID0gIk51bWJlciBvZiBNdWx0aXBsaWVycyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArICAKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIwIiA9ICJOb25lIiwgIjEiID0gIk9uZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyIiA9ICJUd28iKSkgKwogICNzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gcXVhbnRpbGUoZCRmaXhEdXIsIGMoMC4xLCAwLjkpKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhjb21wYXJpc29ucyA9IG15X2NvbXBhcmlzb25zKSsgIyBBZGQgcGFpcndpc2UgY29tcGFyaXNvbnMgcC12YWx1ZQogIHN0YXRfY29tcGFyZV9tZWFucyhsYWJlbC55ID0gMTMpICsgICAgICMgQWRkIGdsb2JhbCBwLXZhbHVlCiAgZ2VvbV90ZXh0KGRhdGEgPSBwX21lZHMsIGFlcyh4ID0gbXVsdE51bSwgeSA9IG1lZCwgbGFiZWwgPSBtZWQpLCAKICAgICAgICAgICAgICBzaXplID0gMywgdmp1c3QgPSAtMS41KSArCiAgZ2d0aXRsZSgiUlQgRGlzdHJpYnV0aW9uIHZzLiBOdW1iZXIgb2YgTXVsdGlwbGllcnMiKQoKcDAKYGBgCgojIyBSVCBieSBNdWx0IGZvciAiRGlmZmljdWx0IiB0cmlhbHMKYGBge3J9CiMgY3JlYXRlIG1lZGlhbnMgdG8gaW5zZXJ0IGFzIHRleHQKZDwtIFNfTQpkIDwtIGRbZCRhYnNTdW1tZWRWYWw8MC41LCBdICMgbGltaXQgdG8gYWJzb2x1dGUgc3VtbWVkIHZhbHVlcyBiZWxvdyAwLjUwCnggPC0gZAp4JG11bHROdW0gPSBkJG11bHROdW0rMQpwX21lZHMgPC0gZGRwbHkoeCwgLihtdWx0TnVtKSwgc3VtbWFyaXNlLCBtZWQgPSBtZWRpYW4ocnQpKQpwX21lZHMkbWVkID0gcm91bmQocF9tZWRzJG1lZCwgZGlnaXRzID0gMikgICMgcm91bmQgdG8gdHdvIGRlY2ltYWwgdmFsdWVzCgojIExpc3Qgb2YgY29uZGl0aW9ucyB0byBjb21wYXJlCm15X2NvbXBhcmlzb25zIDwtIGxpc3QoIGMoIjAiLCAiMSIpLCBjKCIwIiwgIjIiKSwgYygiMSIsICIyIikgKQoKcDAgPSBnZ2JveHBsb3QoZCwgeCA9ICJtdWx0TnVtIiwgeSA9ICJydCIsIGNvbG9yID0gIm11bHROdW0iLCBwYWxldHRlID0gImpjbyIgKSsgI291dGxpZXIuc2hhcGU9TkEKICAKICBsYWJzKHkgPSAiVG90YWwgUlQgKHNlY29uZHMpIiwgeCA9ICJOdW1iZXIgb2YgTXVsdGlwbGllcnMiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKyAgCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiMCIgPSAiTm9uZSIsICIxIiA9ICJPbmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMiIgPSAiVHdvIikpICsKICAjc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IHF1YW50aWxlKGQkZml4RHVyLCBjKDAuMSwgMC45KSkpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucykrICMgQWRkIHBhaXJ3aXNlIGNvbXBhcmlzb25zIHAtdmFsdWUKICBzdGF0X2NvbXBhcmVfbWVhbnMobGFiZWwueSA9IDEzKSArICAgICAjIEFkZCBnbG9iYWwgcC12YWx1ZQogIGdlb21fdGV4dChkYXRhID0gcF9tZWRzLCBhZXMoeCA9IG11bHROdW0sIHkgPSBtZWQsIGxhYmVsID0gbWVkKSwgCiAgICAgICAgICAgICAgc2l6ZSA9IDMsIHZqdXN0ID0gLTEuNSkgKwogIGdndGl0bGUoIlJUIERpc3RyaWJ1dGlvbiB2cy4gTnVtYmVyIG9mIE11bHRpcGxpZXJzOiBBYnNvbHV0ZSBTdW1tZWQgVmFsdWUgPCAkMC41MCIpCgpwMApgYGAKCgojIyBSVCBieSBNdWx0IGZvciAiRWFzeSIgdHJpYWxzCgpgYGB7cn0KIyBjcmVhdGUgbWVkaWFucyB0byBpbnNlcnQgYXMgdGV4dApkPC0gU19NCmQgPC0gZFtkJGFic1N1bW1lZFZhbD4xLjAsIF0gIyBsaW1pdCB0byBhYnNvbHV0ZSBzdW1tZWQgdmFsdWVzIGJlbG93IDAuNTAKeCA8LSBkCngkbXVsdE51bSA9IGQkbXVsdE51bSsxCnBfbWVkcyA8LSBkZHBseSh4LCAuKG11bHROdW0pLCBzdW1tYXJpc2UsIG1lZCA9IG1lZGlhbihydCkpCnBfbWVkcyRtZWQgPSByb3VuZChwX21lZHMkbWVkLCBkaWdpdHMgPSAyKSAgIyByb3VuZCB0byB0d28gZGVjaW1hbCB2YWx1ZXMKCiMgTGlzdCBvZiBjb25kaXRpb25zIHRvIGNvbXBhcmUKbXlfY29tcGFyaXNvbnMgPC0gbGlzdCggYygiMCIsICIxIiksIGMoIjAiLCAiMiIpLCBjKCIxIiwgIjIiKSApCgpwMCA9IGdnYm94cGxvdChkLCB4ID0gIm11bHROdW0iLCB5ID0gInJ0IiwgY29sb3IgPSAibXVsdE51bSIsIHBhbGV0dGUgPSAiamNvIiApKyAjb3V0bGllci5zaGFwZT1OQQogIAogIGxhYnMoeSA9ICJUb3RhbCBSVCAoc2Vjb25kcykiLCB4ID0gIk51bWJlciBvZiBNdWx0aXBsaWVycyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArICAKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIwIiA9ICJOb25lIiwgIjEiID0gIk9uZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyIiA9ICJUd28iKSkgKwogICNzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gcXVhbnRpbGUoZCRmaXhEdXIsIGMoMC4xLCAwLjkpKSkgKwogIHN0YXRfY29tcGFyZV9tZWFucyhjb21wYXJpc29ucyA9IG15X2NvbXBhcmlzb25zKSsgIyBBZGQgcGFpcndpc2UgY29tcGFyaXNvbnMgcC12YWx1ZQogIHN0YXRfY29tcGFyZV9tZWFucyhsYWJlbC55ID0gMTMpICsgICAgICMgQWRkIGdsb2JhbCBwLXZhbHVlCiAgZ2VvbV90ZXh0KGRhdGEgPSBwX21lZHMsIGFlcyh4ID0gbXVsdE51bSwgeSA9IG1lZCwgbGFiZWwgPSBtZWQpLCAKICAgICAgICAgICAgICBzaXplID0gMywgdmp1c3QgPSAtMS41KSArCiAgZ2d0aXRsZSgiUlQgRGlzdHJpYnV0aW9uIHZzLiBOdW1iZXIgb2YgTXVsdGlwbGllcnM6IEFic29sdXRlIFN1bW1lZCBWYWx1ZSA+ICQxLjAwIikKCnAwCgpkPC0gU19NCmQgPC0gZFtkJGFic1N1bW1lZFZhbDwwLjI1LCBdICMgbGltaXQgdG8gYWJzb2x1dGUgc3VtbWVkIHZhbHVlcyBiZWxvdyAwLjUwCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZCwgbXVsdE51bSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShtZWRpYW4gPSBtZWFuKGNvcnJlY3QsIG5hLnJtID0gVCkpCnN1YmplY3RfbWVhbnMKCmBgYAoKIyMgV2hhdCBpcyB0aGUgbWVhbiBhYnMgdmFsdWUgb2YgY29tYm9zIHdpdGggMC8xLzIgbXVsdHM/CiMjIyBIaWdoZXN0IGZvciAxIG11bHRpcGxpZXIKCmBgYHtyfQpkIDwtIFNfTQoKZDAgPC0gZFtkJG11bHROdW0gPT0gMCwgXQpkMSA8LSBkW2QkbXVsdE51bSA9PSAxLCBdCmQyIDwtIGRbZCRtdWx0TnVtID09IDIsIF0KCm1lYW4oZDAkYWJzU3VtbWVkVmFsKQptZWFuKGQxJGFic1N1bW1lZFZhbCkKbWVhbihkMiRhYnNTdW1tZWRWYWwpCmBgYAojIFBTWUNIT01FVFJJQ1MKIyMgU3R1ZHkgMS9TdHVkeSAyLCBSVCBhbmQgQWNjdXJhY3kKCmBgYHtyfQpsb2FkKCJEYXRhL05TX00uUmRhdGEiKQpkMSA8LSBOU19NCmQyIDwtIFNfTQoKIyBDcmVhdGUgSUQgZm9yIGVhY2ggREYKZDEkc3R1ZHkgPC0gIlN0YW5kYXJkIE11bHQuIgpkMiRzdHVkeSA8LSAiU3dhcCBNdWx0LiIKCiMgTmVlZCB0byB1bmlxdWVseSBudW1iZXIgU3ViamVjdHMKZDIkc3ViamVjdCA8LSBkMiRzdWJqZWN0ICsgMTAwCgojIENvbmNhdCBERnMKY29tbW9uX2NvbHMgPC0gaW50ZXJzZWN0KGNvbG5hbWVzKGQxKSwgY29sbmFtZXMoZDIpKQpkZiA9IHJiaW5kKAogIGQxWywgY29tbW9uX2NvbHNdLCAKICBkMlssIGNvbW1vbl9jb2xzXQopCgojIEdST1VQQlkKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShkZiwgc3ViamVjdCwgc3R1ZHkpICU+JQogIGRwbHlyOjpzdW1tYXJpemUoYWNjdXJhY3kgPSBtZWFuKGNvcnJlY3QsIG5hLnJtID0gVCksIHJ0ID0gbWVhbihydCwgbmEucm0gPSBUKSwgbWVhblN3YXAgPSBtZWFuKHN3YXBBbW91bnQsIG5hLnJtID0gVCkpCnN1YmplY3RfbWVhbnMKCiMgTWVhbiBhbmQgU0QgZm9yIGJvdGggc3R1ZGllcwojIFN0dWR5IDE6IEFjY3VyYWN5Cm1lYW4oc3ViamVjdF9tZWFucyRhY2N1cmFjeVtzdWJqZWN0X21lYW5zJHN0dWR5ID09ICJTdGFuZGFyZCBNdWx0LiJdKQpzZChzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkc3R1ZHkgPT0gIlN0YW5kYXJkIE11bHQuIl0pCgojIFN0dWR5IDI6IEFjY3VyYWN5Cm1lYW4oc3ViamVjdF9tZWFucyRhY2N1cmFjeVtzdWJqZWN0X21lYW5zJHN0dWR5ID09ICJTd2FwIE11bHQuIl0pCnNkKHN1YmplY3RfbWVhbnMkYWNjdXJhY3lbc3ViamVjdF9tZWFucyRzdHVkeSA9PSAiU3dhcCBNdWx0LiJdKQoKIyBTaWduaWZpY2FuY2UKdC50ZXN0KHN1YmplY3RfbWVhbnMkYWNjdXJhY3lbc3ViamVjdF9tZWFucyRzdHVkeSA9PSAiU3RhbmRhcmQgTXVsdC4iXSwgc3ViamVjdF9tZWFucyRhY2N1cmFjeVtzdWJqZWN0X21lYW5zJHN0dWR5ID09ICJTd2FwIE11bHQuIl0pCgojIFN0dWR5IDE6IFJUCm1lYW4oc3ViamVjdF9tZWFucyRydFtzdWJqZWN0X21lYW5zJHN0dWR5ID09ICJTdGFuZGFyZCBNdWx0LiJdKQpzZChzdWJqZWN0X21lYW5zJHJ0W3N1YmplY3RfbWVhbnMkc3R1ZHkgPT0gIlN0YW5kYXJkIE11bHQuIl0pCgojIFN0dWR5IDI6IFJUCm1lYW4oc3ViamVjdF9tZWFucyRydFtzdWJqZWN0X21lYW5zJHN0dWR5ID09ICJTd2FwIE11bHQuIl0pCnNkKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRzdHVkeSA9PSAiU3dhcCBNdWx0LiJdKQoKdC50ZXN0KHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRzdHVkeSA9PSAiU3RhbmRhcmQgTXVsdC4iXSwgc3ViamVjdF9tZWFucyRydFtzdWJqZWN0X21lYW5zJHN0dWR5ID09ICJTd2FwIE11bHQuIl0pCgojIFN0dWR5IDI6IFN3YXBzCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZDIsIHN1YmplY3QsIHN0dWR5KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGFjY3VyYWN5ID0gbWVhbihjb3JyZWN0LCBuYS5ybSA9IFQpLCBydCA9IG1lYW4ocnQsIG5hLnJtID0gVCksIG1lYW5Td2FwID0gbWVhbihzd2FwQW1vdW50LCBuYS5ybSA9IFQpKQpzdWJqZWN0X21lYW5zCgptZWFuKHN1YmplY3RfbWVhbnMkbWVhblN3YXApCnNkKHN1YmplY3RfbWVhbnMkbWVhblN3YXApCgpgYGAKCgojIyBDcmVhdGUgQmlubmVkIFZhbHVlcyB0byB0ZXN0IGFnYWluc3QgQWNjdXJhY3kgYW5kIFJUCgpgYGB7cn0KIyBGaWd1cmUgb3V0IGhpc3RvZ3JhbSBiaW4gc2l6ZSwgYmFzZWQgb24gZXF1YWwgbnVtYmVycyBvZiBvYnNlcnZhdGlvbnMKbGlicmFyeShIbWlzYykgIyBjdXQyCgpkIDwtIFNfTQpkJGNob2ljZVtkJGNob2ljZSA9PSAtMV0gPSAwICMgLTEgZm9yIFRhdmFyZXMgbmVlZHMgdG8gYmUgMCBpbiBvcmRlciB0byBjYWxjdWxhdGUgcHJvYi4KCiMgSG93IG1hbnkgYmlucz8KbnVtQmlucyA9IDE5ICMgc2FtZSBhcyBLcmFqYmljaAoKIyBTVU1NRUQgVkFMCmQkdmFsQmluIDwtIGFzLm51bWVyaWMoY3V0MihkJHN1bW1lZFZhbCwgZz1udW1CaW5zKSkKZCR2YWxCaW5BbXQgPC0gY3V0MihkJHN1bW1lZFZhbCwgZz1udW1CaW5zKQpkJHZhbEJpbkN0ciA8LSBjdXQyKGQkc3VtbWVkVmFsLCBnPW51bUJpbnMsIGxldmVscy5tZWFuPVRSVUUpCnZhbHMgPSBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcih1bmlxdWUoZCR2YWxCaW5DdHIpKSkKdmFscyA9IHNvcnQodmFscykKCiMgRk9SIFJUCnN1YmplY3RfbWVhbnNfcnQgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCwgdmFsQmluQ3RyKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHJ0ID0gbWVhbihydCwgbmEucm0gPSBUKSkKc3ViamVjdF9tZWFuc19ydAoKIyBGT1IgQUNDVVJBQ1kKc3ViamVjdF9tZWFuc19hY2MgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCwgdmFsQmluQ3RyKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGNvcnJlY3QgPSBtZWFuKGNvcnJlY3QsIG5hLnJtID0gVCkpCnN1YmplY3RfbWVhbnNfYWNjCgojIEZPUiBDSE9JQ0UKc3ViamVjdF9tZWFuc19jaG9pY2UgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCwgdmFsQmluQ3RyKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGFjY2VwdCA9IG1lYW4oY2hvaWNlLCBuYS5ybSA9IFQpKQpzdWJqZWN0X21lYW5zX2Nob2ljZQoKIyBDcmVhdGUgREYgd2l0aCBhbGwgYmlucyBhcyBjb2x1bW5zCiMgRk9SIFJUCnN1YmplY3RfbWVhbnNfd2lkZV9ydCA8LQogIHNwcmVhZChzdWJqZWN0X21lYW5zX3J0LAogICAgICAgICBrZXkgPSB2YWxCaW5DdHIsCiAgICAgICAgIHZhbHVlID0gcnQsCiAgICAgICAgIHNlcCA9ICJfIikKCiMgRk9SIEFDQ1VSQUNZCnN1YmplY3RfbWVhbnNfd2lkZV9hY2MgPC0KICBzcHJlYWQoc3ViamVjdF9tZWFuc19hY2MsCiAgICAgICAgIGtleSA9IHZhbEJpbkN0ciwKICAgICAgICAgdmFsdWUgPSBjb3JyZWN0LAogICAgICAgICBzZXAgPSAiXyIpCgojIEZPUiBDSE9JQ0UKc3ViamVjdF9tZWFuc193aWRlX2Nob2ljZSA8LQogIHNwcmVhZChzdWJqZWN0X21lYW5zX2Nob2ljZSwKICAgICAgICAga2V5ID0gdmFsQmluQ3RyLAogICAgICAgICB2YWx1ZSA9IGFjY2VwdCwKICAgICAgICAgc2VwID0gIl8iKQoKIyBERiB3aXRoIG1lYW4gYW5kIFNEIGZvciBlYWNoIGJpbgoKcnRfeCA9IHNhcHBseShzdWJqZWN0X21lYW5zX3dpZGVfcnQsIGZ1bmN0aW9uKGNsKSBsaXN0KG1lYW5zPW1lYW4oY2wsbmEucm09VFJVRSksIHNkcz1zZChjbCxuYS5ybT1UUlVFKSkpCnJ0X3ggPSB0KHJ0X3gpCmFjY194ID0gc2FwcGx5KHN1YmplY3RfbWVhbnNfd2lkZV9hY2MsIGZ1bmN0aW9uKGNsKSBsaXN0KG1lYW5zPW1lYW4oY2wsbmEucm09VFJVRSksIHNkcz1zZChjbCxuYS5ybT1UUlVFKSkpCmFjY194ID0gdChhY2NfeCkKY2hvaWNlX3ggPSBzYXBwbHkoc3ViamVjdF9tZWFuc193aWRlX2Nob2ljZSwgZnVuY3Rpb24oY2wpIGxpc3QobWVhbnM9bWVhbihjbCxuYS5ybT1UUlVFKSwgc2RzPXNkKGNsLG5hLnJtPVRSVUUpKSkKY2hvaWNlX3ggPSB0KGNob2ljZV94KQoKIyBNRUFOcwpydF9tZWFuID0gbnVtZXJpYygpCmFjY19tZWFuID0gbnVtZXJpYygpCmNob2ljZV9tZWFuID0gbnVtZXJpYygpCmZvcihpIGluIDI6MjApewogIHJ0X21lYW4gPSBjKHJ0X21lYW4sIHJ0X3hbaSwxXVtbMV1dKQogIGFjY19tZWFuID0gYyhhY2NfbWVhbiwgYWNjX3hbaSwxXVtbMV1dKQogIGNob2ljZV9tZWFuID0gYyhjaG9pY2VfbWVhbiwgY2hvaWNlX3hbaSwxXVtbMV1dKQp9CgojIFNEcwpydF9zZCA9IG51bWVyaWMoKQphY2Nfc2QgPSBudW1lcmljKCkKY2hvaWNlX3NkID0gbnVtZXJpYygpCmZvcihpIGluIDI6MjApewogIHJ0X3NkID0gYyhydF9zZCwgcnRfeFtpLDJdW1sxXV0pCiAgYWNjX3NkID0gYyhhY2Nfc2QsIGFjY194W2ksMl1bWzFdXSkKICBjaG9pY2Vfc2QgPSBjKGNob2ljZV9zZCwgY2hvaWNlX3hbaSwyXVtbMV1dKQp9CgojIENyZWF0ZSBERgpkZiA9IGRhdGEuZnJhbWUoInZhbCIgPSB2YWxzLAogICAgICAgICAgICAgICAgInJ0X21lYW4iID0gcnRfbWVhbiwgInJ0X3NkIiA9IHJ0X3NkLAogICAgICAgICAgICAgICAgImFjY19tZWFuIiA9IGFjY19tZWFuLCAiYWNjX3NkIiA9IGFjY19zZCwKICAgICAgICAgICAgICAgICJjaG9pY2VfbWVhbiIgPSBjaG9pY2VfbWVhbiwgImNob2ljZV9zZCIgPSBjaG9pY2Vfc2QpCgojIEFkZCBTRXMKblZhbCA9IHNxcnQobGVuZ3RoKHVuaXF1ZShkJHN1YmplY3QpKSkgIyBjYWxjdWxhdGUgdGhlIGRlbm9taW5hdG9yIG9mIHRoZSBTRSBlcXVhdGlvbgpkZiRydF9zZSA8LSBkZiRydF9zZC9uVmFsCmRmJGFjY19zZSA8LSBkZiRhY2Nfc2QvblZhbApkZiRjaG9pY2Vfc2UgPC0gZGYkY2hvaWNlX3NkL25WYWwKCiMtLS0tLS0tLS0tLSMKIyBQTE9UICAgICAgIyAKIy0tLS0tLS0tLS0tIwoKIyBSVApnZ3Bsb3QoZGF0YSA9IGRmLGFlcyh4ID0gdmFsLHkgPSBydF9tZWFuKSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICAjZ2VvbV9saW5lKCkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBydF9tZWFuLXJ0X3NlLHltYXggPSBydF9tZWFuK3J0X3NlKSkgKyAKICBsYWJzKHggPSAiTmV0IFZhbHVlIiwgeSA9ICJSZWFjdGlvbiBUaW1lIChzZWNvbmRzKSIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGdndGl0bGUoIk1lYW4gUmVhY3Rpb24gVGltZSBieSBOZXQgVmFsdWUiKQogIAojIEFDQ1VSQUNZCmdncGxvdChkYXRhID0gZGYsYWVzKHggPSB2YWwseSA9IGFjY19tZWFuKSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICAjZ2VvbV9saW5lKCkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBhY2NfbWVhbi1hY2Nfc2UsIHltYXggPSBhY2NfbWVhbithY2Nfc2UpKSArIAogIGxhYnMoeCA9ICJOZXQgVmFsdWUiLCB5ID0gInAoQ29ycmVjdCkiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBnZ3RpdGxlKCJCIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMikpCiMgIGdndGl0bGUoInAoQ29ycmVjdCkgYnkgTmV0IFZhbHVlICIpCgojIENIT0lDRQpnZ3Bsb3QoZGF0YSA9IGRmLGFlcyh4ID0gdmFsLHkgPSBjaG9pY2VfbWVhbikpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgI2dlb21fbGluZSgpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gY2hvaWNlX21lYW4tY2hvaWNlX3NlLCB5bWF4ID0gY2hvaWNlX21lYW4rY2hvaWNlX3NlKSkgKyAKICBsYWJzKHggPSAiTmV0IFZhbHVlIiwgeSA9ICJwKEFjY2VwdCkiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMywzLDAuNSkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoc2l6ZT0xNyksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNykpCiAgI2dndGl0bGUoIkEiKSArCiAgI3RoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMikpCgpzZXR3ZCgiL1VzZXJzL2Rqdy9Ecm9wYm94L1BIRC9QUkVTRU5UQVRJT05TLzIwMTdfU05FL1Bsb3RzIikKZ2dzYXZlKCJQcm9iLnBuZyIsIHdpZHRoID0gMTksIGhlaWdodCA9IDEyLCB1bml0cyA9ICJjbSIpCgojVC1URVNUIGZvciB0cmlhbHMKI3QudGVzdChzdWJqZWN0X21lYW5zX3dpZGUkZmxpcF8xLCBzdWJqZWN0X21lYW5zX3dpZGUkZmxpcF8yLCBwYWlyZWQgPSBUUlVFKQpgYGAKCiMjIFNhbWUgYXMgYWJvdmUgYnV0IGZvciBhYnMgVmFsIGZvciBSVCBhbmQgRml4YXRpb24KCmBgYHtyfQojIEFCUyBWYWwKZCA8LSBTX00KZCRjaG9pY2VbZCRjaG9pY2UgPT0gLTFdID0gMCAjIC0xIGZvciBUYXZhcmVzIG5lZWRzIHRvIGJlIDAgaW4gb3JkZXIgdG8gY2FsY3VsYXRlIHByb2IuCgpkJGFic1ZhbEJpbiA8LSBhcy5udW1lcmljKGN1dDIoZCRhYnNTdW1tZWRWYWwsIGc9OSkpCmQkYWJzVmFsQmluQW10IDwtIGN1dDIoZCRhYnNTdW1tZWRWYWwsIGc9OSkKZCRhYnNWYWxCaW5DdHIgPC0gY3V0MihkJGFic1N1bW1lZFZhbCwgZz05LCBsZXZlbHMubWVhbj1UUlVFKQphYnNWYWxzID0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIodW5pcXVlKGQkYWJzVmFsQmluQ3RyKSkpCmFic1ZhbHMgPSBzb3J0KGFic1ZhbHMpCgojIEFicyBWYWwgUlQKYWJzX3N1YmplY3RfbWVhbnNfcnQgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCwgYWJzVmFsQmluQ3RyKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHJ0ID0gbWVhbihydCwgbmEucm0gPSBUKSkKYWJzX3N1YmplY3RfbWVhbnNfcnQKCiMgRk9SIEZpeGF0aW9ucwphYnNfc3ViamVjdF9tZWFuc19maXggPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCwgYWJzVmFsQmluQ3RyKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGZpeGF0aW9ucyA9IG1lYW4oc3dhcEFtb3VudCwgbmEucm0gPSBUKSkKYWJzX3N1YmplY3RfbWVhbnNfZml4CgojIENyZWF0ZSBERiB3aXRoIGFsbCBiaW5zIGFzIGNvbHVtbnMKIyBGT1IgUlQKYWJzX3N1YmplY3RfbWVhbnNfd2lkZV9ydCA8LQogIHNwcmVhZChhYnNfc3ViamVjdF9tZWFuc19ydCwKICAgICAgICAga2V5ID0gYWJzVmFsQmluQ3RyLAogICAgICAgICB2YWx1ZSA9IHJ0LAogICAgICAgICBzZXAgPSAiXyIpCgojIEZPUiBBQ0NVUkFDWQphYnNfc3ViamVjdF9tZWFuc193aWRlX2ZpeCA8LQogIHNwcmVhZChhYnNfc3ViamVjdF9tZWFuc19maXgsCiAgICAgICAgIGtleSA9IGFic1ZhbEJpbkN0ciwKICAgICAgICAgdmFsdWUgPSBmaXhhdGlvbnMsCiAgICAgICAgIHNlcCA9ICJfIikKCiMgREYgd2l0aCBtZWFuIGFuZCBTRCBmb3IgZWFjaCBiaW4KCnJ0X3ggPSBzYXBwbHkoYWJzX3N1YmplY3RfbWVhbnNfd2lkZV9ydCwgZnVuY3Rpb24oY2wpIGxpc3QobWVhbnM9bWVhbihjbCxuYS5ybT1UUlVFKSwgc2RzPXNkKGNsLG5hLnJtPVRSVUUpKSkKcnRfeCA9IHQocnRfeCkKZml4X3ggPSBzYXBwbHkoYWJzX3N1YmplY3RfbWVhbnNfd2lkZV9maXgsIGZ1bmN0aW9uKGNsKSBsaXN0KG1lYW5zPW1lYW4oY2wsbmEucm09VFJVRSksIHNkcz1zZChjbCxuYS5ybT1UUlVFKSkpCmZpeF94ID0gdChmaXhfeCkKCnJ0X3gKCnJ0X21lYW4gPSBudW1lcmljKCkKZml4X21lYW4gPSBudW1lcmljKCkKZm9yKGkgaW4gMjoxMCl7CiAgcnRfbWVhbiA9IGMocnRfbWVhbiwgcnRfeFtpLDFdW1sxXV0pCiAgZml4X21lYW4gPSBjKGZpeF9tZWFuLCBmaXhfeFtpLDFdW1sxXV0pCn0KCnJ0X3NkID0gbnVtZXJpYygpCmZpeF9zZCA9IG51bWVyaWMoKQpmb3IoaSBpbiAyOjEwKXsKICBydF9zZCA9IGMocnRfc2QsIHJ0X3hbaSwyXVtbMV1dKQogIGZpeF9zZCA9IGMoZml4X3NkLCBmaXhfeFtpLDJdW1sxXV0pCn0KCgpkZiA9IGRhdGEuZnJhbWUoImFic192YWwiID0gYWJzVmFscywgInJ0X21lYW4iID0gcnRfbWVhbiwgInJ0X3NkIiA9IHJ0X3NkLCAiZml4X21lYW4iID0gZml4X21lYW4sICJmaXhfc2QiID0gZml4X3NkKQpuVmFsID0gc3FydChsZW5ndGgodW5pcXVlKGQkc3ViamVjdCkpKSAjIGNhbGN1bGF0ZSB0aGUgZGVub21pbmF0b3Igb2YgdGhlIFNFIGVxdWF0aW9uCmRmJHJ0X3NlIDwtIGRmJHJ0X3NkL25WYWwKZGYkZml4X3NlIDwtIGRmJGZpeF9zZC9uVmFsCmRmCgojLS0tLS0tLS0tLS0jCiMgUExPVCAgICAgICMgCiMtLS0tLS0tLS0tLSMKCiMgUlQKZ2dwbG90KGRhdGEgPSBkZixhZXMoeCA9IGFic192YWwseSA9IHJ0X21lYW4pKSArIAogIGdlb21fcG9pbnQoKSArIAogICNnZW9tX2xpbmUoKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHJ0X21lYW4tcnRfc2UseW1heCA9IHJ0X21lYW4rcnRfc2UpKSArIAogIGxhYnMoeCA9ICJBYnNvbHV0ZSBOZXQgVmFsdWUgKCQpIiwgeSA9ICJSZWFjdGlvbiBUaW1lIChzKSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsMywwLjUpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgyLjIsMy44LDAuMikpICsKICB0aGVtZV9taW5pbWFsKCkrCiAgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChzaXplPTE4KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4KSkKICBnZ3RpdGxlKCJNZWFuIFJlYWN0aW9uIFRpbWUgYnkgQWJzb2x1dGUgTmV0IFZhbHVlIikKICAKIyBGSVhBVElPTlMKZ2dwbG90KGRhdGEgPSBkZixhZXMoeCA9IGFic192YWwseSA9IGZpeF9tZWFuKSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICAjZ2VvbV9saW5lKCkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBmaXhfbWVhbi1maXhfc2UsIHltYXggPSBmaXhfbWVhbitmaXhfc2UpKSArIAogIGxhYnMoeCA9ICJBYnNvbHV0ZSBOZXQgVmFsdWUgKCQpIiwgeSA9ICJGaXhhdGlvbiBDb3VudCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsMywwLjUpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgyLjQsMy41LDAuMSkpICsKICB0aGVtZV9taW5pbWFsKCkrCiAgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChzaXplPTE3KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE3KSkKICBnZ3RpdGxlKCJGaXhhdGlvbnMgYnkgQWJzb2x1dGUgTmV0IFZhbHVlICIpCiAgCnNldHdkKCIvVXNlcnMvZGp3L0Ryb3Bib3gvUEhEL1BSRVNFTlRBVElPTlMvMjAxN19TTkUvUGxvdHMiKQpnZ3NhdmUoIlJULnBuZyIsIHdpZHRoID0gMTksIGhlaWdodCA9IDEyLCB1bml0cyA9ICJjbSIpCiAgCgpgYGAKCgojIEZVTkNUSU9OUyBmb3IgU1VNTUFSWSBTVEFUUwojIyMgRnJvbTogaHR0cDovL3d3dy5jb29rYm9vay1yLmNvbS9HcmFwaHMvUGxvdHRpbmdfbWVhbnNfYW5kX2Vycm9yX2JhcnNfKGdncGxvdDIpLyNIZWxwZXIlMjBmdW5jdGlvbnMKCmBgYHtyfQojIyBOb3JtcyB0aGUgZGF0YSB3aXRoaW4gc3BlY2lmaWVkIGdyb3VwcyBpbiBhIGRhdGEgZnJhbWU7IGl0IG5vcm1hbGl6ZXMgZWFjaAojIyBzdWJqZWN0IChpZGVudGlmaWVkIGJ5IGlkdmFyKSBzbyB0aGF0IHRoZXkgaGF2ZSB0aGUgc2FtZSBtZWFuLCB3aXRoaW4gZWFjaCBncm91cAojIyBzcGVjaWZpZWQgYnkgYmV0d2VlbnZhcnMuCiMjICAgZGF0YTogYSBkYXRhIGZyYW1lLgojIyAgIGlkdmFyOiB0aGUgbmFtZSBvZiBhIGNvbHVtbiB0aGF0IGlkZW50aWZpZXMgZWFjaCBzdWJqZWN0IChvciBtYXRjaGVkIHN1YmplY3RzKQojIyAgIG1lYXN1cmV2YXI6IHRoZSBuYW1lIG9mIGEgY29sdW1uIHRoYXQgY29udGFpbnMgdGhlIHZhcmlhYmxlIHRvIGJlIHN1bW1hcmllemVkCiMjICAgYmV0d2VlbnZhcnM6IGEgdmVjdG9yIGNvbnRhaW5pbmcgbmFtZXMgb2YgY29sdW1ucyB0aGF0IGFyZSBiZXR3ZWVuLXN1YmplY3RzIHZhcmlhYmxlcwojIyAgIG5hLnJtOiBhIGJvb2xlYW4gdGhhdCBpbmRpY2F0ZXMgd2hldGhlciB0byBpZ25vcmUgTkEncwpub3JtRGF0YVdpdGhpbiA8LSBmdW5jdGlvbihkYXRhPU5VTEwsIGlkdmFyLCBtZWFzdXJldmFyLCBiZXR3ZWVudmFycz1OVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybT1GQUxTRSwgLmRyb3A9VFJVRSkgewogICAgbGlicmFyeShwbHlyKQoKICAgICMgTWVhc3VyZSB2YXIgb24gbGVmdCwgaWR2YXIgKyBiZXR3ZWVuIHZhcnMgb24gcmlnaHQgb2YgZm9ybXVsYS4KICAgIGRhdGEuc3Viak1lYW4gPC0gZGRwbHkoZGF0YSwgYyhpZHZhciwgYmV0d2VlbnZhcnMpLCAuZHJvcD0uZHJvcCwKICAgICAuZnVuID0gZnVuY3Rpb24oeHgsIGNvbCwgbmEucm0pIHsKICAgICAgICBjKHN1YmpNZWFuID0gbWVhbih4eFssY29sXSwgbmEucm09bmEucm0pKQogICAgICB9LAogICAgICBtZWFzdXJldmFyLAogICAgICBuYS5ybQogICAgKQoKICAgICMgUHV0IHRoZSBzdWJqZWN0IG1lYW5zIHdpdGggb3JpZ2luYWwgZGF0YQogICAgZGF0YSA8LSBtZXJnZShkYXRhLCBkYXRhLnN1YmpNZWFuKQoKICAgICMgR2V0IHRoZSBub3JtYWxpemVkIGRhdGEgaW4gYSBuZXcgY29sdW1uCiAgICBtZWFzdXJlTm9ybWVkVmFyIDwtIHBhc3RlKG1lYXN1cmV2YXIsICJfbm9ybSIsIHNlcD0iIikKICAgIGRhdGFbLG1lYXN1cmVOb3JtZWRWYXJdIDwtIGRhdGFbLG1lYXN1cmV2YXJdIC0gZGF0YVssInN1YmpNZWFuIl0gKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVhbihkYXRhWyxtZWFzdXJldmFyXSwgbmEucm09bmEucm0pCgogICAgIyBSZW1vdmUgdGhpcyBzdWJqZWN0IG1lYW4gY29sdW1uCiAgICBkYXRhJHN1YmpNZWFuIDwtIE5VTEwKCiAgICByZXR1cm4oZGF0YSkKfQoKIyMgU3VtbWFyaXplcyBkYXRhLCBoYW5kbGluZyB3aXRoaW4tc3ViamVjdHMgdmFyaWFibGVzIGJ5IHJlbW92aW5nIGludGVyLXN1YmplY3QgdmFyaWFiaWxpdHkuCiMjIEl0IHdpbGwgc3RpbGwgd29yayBpZiB0aGVyZSBhcmUgbm8gd2l0aGluLVMgdmFyaWFibGVzLgojIyBHaXZlcyBjb3VudCwgdW4tbm9ybWVkIG1lYW4sIG5vcm1lZCBtZWFuICh3aXRoIHNhbWUgYmV0d2Vlbi1ncm91cCBtZWFuKSwKIyMgICBzdGFuZGFyZCBkZXZpYXRpb24sIHN0YW5kYXJkIGVycm9yIG9mIHRoZSBtZWFuLCBhbmQgY29uZmlkZW5jZSBpbnRlcnZhbC4KIyMgSWYgdGhlcmUgYXJlIHdpdGhpbi1zdWJqZWN0IHZhcmlhYmxlcywgY2FsY3VsYXRlIGFkanVzdGVkIHZhbHVlcyB1c2luZyBtZXRob2QgZnJvbSBNb3JleSAoMjAwOCkuCiMjICAgZGF0YTogYSBkYXRhIGZyYW1lLgojIyAgIG1lYXN1cmV2YXI6IHRoZSBuYW1lIG9mIGEgY29sdW1uIHRoYXQgY29udGFpbnMgdGhlIHZhcmlhYmxlIHRvIGJlIHN1bW1hcmllemVkCiMjICAgYmV0d2VlbnZhcnM6IGEgdmVjdG9yIGNvbnRhaW5pbmcgbmFtZXMgb2YgY29sdW1ucyB0aGF0IGFyZSBiZXR3ZWVuLXN1YmplY3RzIHZhcmlhYmxlcwojIyAgIHdpdGhpbnZhcnM6IGEgdmVjdG9yIGNvbnRhaW5pbmcgbmFtZXMgb2YgY29sdW1ucyB0aGF0IGFyZSB3aXRoaW4tc3ViamVjdHMgdmFyaWFibGVzCiMjICAgaWR2YXI6IHRoZSBuYW1lIG9mIGEgY29sdW1uIHRoYXQgaWRlbnRpZmllcyBlYWNoIHN1YmplY3QgKG9yIG1hdGNoZWQgc3ViamVjdHMpCiMjICAgbmEucm06IGEgYm9vbGVhbiB0aGF0IGluZGljYXRlcyB3aGV0aGVyIHRvIGlnbm9yZSBOQSdzCiMjICAgY29uZi5pbnRlcnZhbDogdGhlIHBlcmNlbnQgcmFuZ2Ugb2YgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgKGRlZmF1bHQgaXMgOTUlKQoKc3VtbWFyeVNFd2l0aGluIDwtIGZ1bmN0aW9uKGRhdGE9TlVMTCwgbWVhc3VyZXZhciwgYmV0d2VlbnZhcnM9TlVMTCwgd2l0aGludmFycz1OVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR2YXI9TlVMTCwgbmEucm09RkFMU0UsIGNvbmYuaW50ZXJ2YWw9Ljk1LCAuZHJvcD1UUlVFKSB7CgogICMgRW5zdXJlIHRoYXQgdGhlIGJldHdlZW52YXJzIGFuZCB3aXRoaW52YXJzIGFyZSBmYWN0b3JzCiAgZmFjdG9ydmFycyA8LSB2YXBwbHkoZGF0YVssIGMoYmV0d2VlbnZhcnMsIHdpdGhpbnZhcnMpLCBkcm9wPUZBTFNFXSwKICAgIEZVTj1pcy5mYWN0b3IsIEZVTi5WQUxVRT1sb2dpY2FsKDEpKQoKICBpZiAoIWFsbChmYWN0b3J2YXJzKSkgewogICAgbm9uZmFjdG9ydmFycyA8LSBuYW1lcyhmYWN0b3J2YXJzKVshZmFjdG9ydmFyc10KICAgIG1lc3NhZ2UoIkF1dG9tYXRpY2FsbHkgY29udmVydGluZyB0aGUgZm9sbG93aW5nIG5vbi1mYWN0b3JzIHRvIGZhY3RvcnM6ICIsCiAgICAgICAgICAgIHBhc3RlKG5vbmZhY3RvcnZhcnMsIGNvbGxhcHNlID0gIiwgIikpCiAgICBkYXRhW25vbmZhY3RvcnZhcnNdIDwtIGxhcHBseShkYXRhW25vbmZhY3RvcnZhcnNdLCBmYWN0b3IpCiAgfQoKICAjIEdldCB0aGUgbWVhbnMgZnJvbSB0aGUgdW4tbm9ybWVkIGRhdGEKICBkYXRhYyA8LSBzdW1tYXJ5U0UoZGF0YSwgbWVhc3VyZXZhciwgZ3JvdXB2YXJzPWMoYmV0d2VlbnZhcnMsIHdpdGhpbnZhcnMpLAogICAgICAgICAgICAgICAgICAgICBuYS5ybT1uYS5ybSwgY29uZi5pbnRlcnZhbD1jb25mLmludGVydmFsLCAuZHJvcD0uZHJvcCkKCiAgIyBEcm9wIGFsbCB0aGUgdW51c2VkIGNvbHVtbnMgKHRoZXNlIHdpbGwgYmUgY2FsY3VsYXRlZCB3aXRoIG5vcm1lZCBkYXRhKQogIGRhdGFjJHNkIDwtIE5VTEwKICBkYXRhYyRzZSA8LSBOVUxMCiAgZGF0YWMkY2kgPC0gTlVMTAoKICAjIE5vcm0gZWFjaCBzdWJqZWN0J3MgZGF0YQogIG5kYXRhIDwtIG5vcm1EYXRhV2l0aGluKGRhdGEsIGlkdmFyLCBtZWFzdXJldmFyLCBiZXR3ZWVudmFycywgbmEucm0sIC5kcm9wPS5kcm9wKQoKICAjIFRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIG5ldyBjb2x1bW4KICBtZWFzdXJldmFyX24gPC0gcGFzdGUobWVhc3VyZXZhciwgIl9ub3JtIiwgc2VwPSIiKQoKICAjIENvbGxhcHNlIHRoZSBub3JtZWQgZGF0YSAtIG5vdyB3ZSBjYW4gdHJlYXQgYmV0d2VlbiBhbmQgd2l0aGluIHZhcnMgdGhlIHNhbWUKICBuZGF0YWMgPC0gc3VtbWFyeVNFKG5kYXRhLCBtZWFzdXJldmFyX24sIGdyb3VwdmFycz1jKGJldHdlZW52YXJzLCB3aXRoaW52YXJzKSwKICAgICAgICAgICAgICAgICAgICAgIG5hLnJtPW5hLnJtLCBjb25mLmludGVydmFsPWNvbmYuaW50ZXJ2YWwsIC5kcm9wPS5kcm9wKQoKICAjIEFwcGx5IGNvcnJlY3Rpb24gZnJvbSBNb3JleSAoMjAwOCkgdG8gdGhlIHN0YW5kYXJkIGVycm9yIGFuZCBjb25maWRlbmNlIGludGVydmFsCiAgIyAgR2V0IHRoZSBwcm9kdWN0IG9mIHRoZSBudW1iZXIgb2YgY29uZGl0aW9ucyBvZiB3aXRoaW4tUyB2YXJpYWJsZXMKICBuV2l0aGluR3JvdXBzICAgIDwtIHByb2QodmFwcGx5KG5kYXRhY1ssd2l0aGludmFycywgZHJvcD1GQUxTRV0sIEZVTj1ubGV2ZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICBGVU4uVkFMVUU9bnVtZXJpYygxKSkpCiAgY29ycmVjdGlvbkZhY3RvciA8LSBzcXJ0KCBuV2l0aGluR3JvdXBzIC8gKG5XaXRoaW5Hcm91cHMtMSkgKQoKICAjIEFwcGx5IHRoZSBjb3JyZWN0aW9uIGZhY3RvcgogIG5kYXRhYyRzZCA8LSBuZGF0YWMkc2QgKiBjb3JyZWN0aW9uRmFjdG9yCiAgbmRhdGFjJHNlIDwtIG5kYXRhYyRzZSAqIGNvcnJlY3Rpb25GYWN0b3IKICBuZGF0YWMkY2kgPC0gbmRhdGFjJGNpICogY29ycmVjdGlvbkZhY3RvcgoKICAjIENvbWJpbmUgdGhlIHVuLW5vcm1lZCBtZWFucyB3aXRoIHRoZSBub3JtZWQgcmVzdWx0cwogIG1lcmdlKGRhdGFjLCBuZGF0YWMpCn0KCiMjIEdpdmVzIGNvdW50LCBtZWFuLCBzdGFuZGFyZCBkZXZpYXRpb24sIHN0YW5kYXJkIGVycm9yIG9mIHRoZSBtZWFuLCBhbmQgY29uZmlkZW5jZSBpbnRlcnZhbCAoZGVmYXVsdCA5NSUpLgojIyAgIGRhdGE6IGEgZGF0YSBmcmFtZS4KIyMgICBtZWFzdXJldmFyOiB0aGUgbmFtZSBvZiBhIGNvbHVtbiB0aGF0IGNvbnRhaW5zIHRoZSB2YXJpYWJsZSB0byBiZSBzdW1tYXJpZXplZAojIyAgIGdyb3VwdmFyczogYSB2ZWN0b3IgY29udGFpbmluZyBuYW1lcyBvZiBjb2x1bW5zIHRoYXQgY29udGFpbiBncm91cGluZyB2YXJpYWJsZXMKIyMgICBuYS5ybTogYSBib29sZWFuIHRoYXQgaW5kaWNhdGVzIHdoZXRoZXIgdG8gaWdub3JlIE5BJ3MKIyMgICBjb25mLmludGVydmFsOiB0aGUgcGVyY2VudCByYW5nZSBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCAoZGVmYXVsdCBpcyA5NSUpCnN1bW1hcnlTRSA8LSBmdW5jdGlvbihkYXRhPU5VTEwsIG1lYXN1cmV2YXIsIGdyb3VwdmFycz1OVUxMLCBuYS5ybT1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGNvbmYuaW50ZXJ2YWw9Ljk1LCAuZHJvcD1UUlVFKSB7CiAgICBsaWJyYXJ5KHBseXIpCgogICAgIyBOZXcgdmVyc2lvbiBvZiBsZW5ndGggd2hpY2ggY2FuIGhhbmRsZSBOQSdzOiBpZiBuYS5ybT09VCwgZG9uJ3QgY291bnQgdGhlbQogICAgbGVuZ3RoMiA8LSBmdW5jdGlvbiAoeCwgbmEucm09RkFMU0UpIHsKICAgICAgICBpZiAobmEucm0pIHN1bSghaXMubmEoeCkpCiAgICAgICAgZWxzZSAgICAgICBsZW5ndGgoeCkKICAgIH0KCiAgICAjIFRoaXMgZG9lcyB0aGUgc3VtbWFyeS4gRm9yIGVhY2ggZ3JvdXAncyBkYXRhIGZyYW1lLCByZXR1cm4gYSB2ZWN0b3Igd2l0aAogICAgIyBOLCBtZWFuLCBhbmQgc2QKICAgIGRhdGFjIDwtIGRkcGx5KGRhdGEsIGdyb3VwdmFycywgLmRyb3A9LmRyb3AsCiAgICAgIC5mdW4gPSBmdW5jdGlvbih4eCwgY29sKSB7CiAgICAgICAgYyhOICAgID0gbGVuZ3RoMih4eFtbY29sXV0sIG5hLnJtPW5hLnJtKSwKICAgICAgICAgIG1lYW4gPSBtZWFuICAgKHh4W1tjb2xdXSwgbmEucm09bmEucm0pLAogICAgICAgICAgc2QgICA9IHNkICAgICAoeHhbW2NvbF1dLCBuYS5ybT1uYS5ybSkKICAgICAgICApCiAgICAgIH0sCiAgICAgIG1lYXN1cmV2YXIKICAgICkKCiAgICAjIFJlbmFtZSB0aGUgIm1lYW4iIGNvbHVtbiAgICAKICAgIGRhdGFjIDwtIHJlbmFtZShkYXRhYywgYygibWVhbiIgPSBtZWFzdXJldmFyKSkKCiAgICBkYXRhYyRzZSA8LSBkYXRhYyRzZCAvIHNxcnQoZGF0YWMkTikgICMgQ2FsY3VsYXRlIHN0YW5kYXJkIGVycm9yIG9mIHRoZSBtZWFuCgogICAgIyBDb25maWRlbmNlIGludGVydmFsIG11bHRpcGxpZXIgZm9yIHN0YW5kYXJkIGVycm9yCiAgICAjIENhbGN1bGF0ZSB0LXN0YXRpc3RpYyBmb3IgY29uZmlkZW5jZSBpbnRlcnZhbDogCiAgICAjIGUuZy4sIGlmIGNvbmYuaW50ZXJ2YWwgaXMgLjk1LCB1c2UgLjk3NSAoYWJvdmUvYmVsb3cpLCBhbmQgdXNlIGRmPU4tMQogICAgY2lNdWx0IDwtIHF0KGNvbmYuaW50ZXJ2YWwvMiArIC41LCBkYXRhYyROLTEpCiAgICBkYXRhYyRjaSA8LSBkYXRhYyRzZSAqIGNpTXVsdAoKICAgIHJldHVybihkYXRhYykKfQpgYGAKCgojIyBEaWZmaWN1bHQsIFZlcnkgRGlmZmljdWx0LCBFYXN5LCBPdmVyYWxsIFJUIGFuZCBBY2N1cmFjeSBieSBNdWx0TnVtCmBgYHtyfQpkIDwtIFNfTQojIFJlbW92ZSBhYnMgc3VtbWVkIHZhbHVlcyA+MS4wMCBhbmQgPDAuNTAKZCA8LSBkWyhkJGFic1N1bW1lZFZhbDw9MC41MCkgfCAoZCRhYnNTdW1tZWRWYWw+PTEuMDApLF0KCiMgQ3JlYXRlIERpZmZpY3VsdHkgTGV2ZWwgYW5kIEZhY3RvciBpdApkJGRpZmZpY3VsdHkgPSAxICAjIGVhc3kgbGV2ZWwKZCRkaWZmaWN1bHR5W2QkYWJzU3VtbWVkVmFsPDAuNV0gPSAyICMgRGlmZmljdWx0IGxldmVsCmQkZGlmZmljdWx0eVtkJGFic1N1bW1lZFZhbDwwLjI1XSA9IDMgIyBWLkRpZmZpY3VsdCBsZXZlbAoKIyBGYWN0b3IgY29uZGl0aW9ucwpkJG11bHROdW0gPC0gZmFjdG9yKGQkbXVsdE51bSkKZCRkaWZmaWN1bHR5IDwtIGZhY3RvcihkJGRpZmZpY3VsdHkpCgojIEZPUiBULVRFU1RTCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCwgZGlmZmljdWx0eSwgbXVsdE51bSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShhY2N1cmFjeSA9IG1lYW4oY29ycmVjdCksIHJ0ID0gbWVhbihydCkpCnN1YmplY3RfbWVhbnMKCiMgUGFpcmVkIFRUZXN0CiMgQWNjdXJhY3kKIyBFYXN5IHZzIEhhcmQKbWVhbihzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAxXSkKbWVhbihzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAzXSkKc2Qoc3ViamVjdF9tZWFucyRhY2N1cmFjeVtzdWJqZWN0X21lYW5zJGRpZmZpY3VsdHkgPT0gMV0pCnNkKHN1YmplY3RfbWVhbnMkYWNjdXJhY3lbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDNdKQogICAgICAgCnQudGVzdChzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAxXSwKICAgICAgIHN1YmplY3RfbWVhbnMkYWNjdXJhY3lbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDNdLCBwYWlyZWQgPSBUUlVFKQoKIyBFYXN5LCAwIE11bHQvMSBNdWx0Cm1lYW4oc3ViamVjdF9tZWFucyRhY2N1cmFjeVtzdWJqZWN0X21lYW5zJGRpZmZpY3VsdHkgPT0gMSAmIHN1YmplY3RfbWVhbnMkbXVsdE51bSA9PSAwXSkKbWVhbihzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAxICYgc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDFdKQpzZChzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAxICYgc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDBdKQpzZChzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAxICYgc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDFdKQoKdC50ZXN0KHN1YmplY3RfbWVhbnMkYWNjdXJhY3lbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDEgJiBzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMF0sCiAgICAgICBzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAxICYgc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDFdLCBwYWlyZWQgPSBUUlVFKQoKIyBIYXJkLCAwIE11bHQvMSBNdWx0Cm1lYW4oc3ViamVjdF9tZWFucyRhY2N1cmFjeVtzdWJqZWN0X21lYW5zJGRpZmZpY3VsdHkgPT0gMyAmIHN1YmplY3RfbWVhbnMkbXVsdE51bSA9PSAwXSkKbWVhbihzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAzICYgc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDFdKQpzZChzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAzICYgc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDBdKQpzZChzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAzICYgc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDFdKQoKdC50ZXN0KHN1YmplY3RfbWVhbnMkYWNjdXJhY3lbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDMgJiBzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMF0sCiAgICAgICBzdWJqZWN0X21lYW5zJGFjY3VyYWN5W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAzICYgc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDFdLCBwYWlyZWQgPSBUUlVFKQoKIyBQYWlyZWQgVFRlc3QKIyBSVAojIEVhc3kgdnMgSGFyZAptZWFuKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDFdKQptZWFuKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDNdKQpzZChzdWJqZWN0X21lYW5zJHJ0W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAxXSkKc2Qoc3ViamVjdF9tZWFucyRydFtzdWJqZWN0X21lYW5zJGRpZmZpY3VsdHkgPT0gM10pCiAgICAgICAKdC50ZXN0KHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDFdLAogICAgICAgc3ViamVjdF9tZWFucyRydFtzdWJqZWN0X21lYW5zJGRpZmZpY3VsdHkgPT0gM10sIHBhaXJlZCA9IFRSVUUpCgojIEVhc3ksIDAgTXVsdC8xIE11bHQKbWVhbihzdWJqZWN0X21lYW5zJHJ0W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAxICYgc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDBdKQptZWFuKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDEgJiBzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMV0pCnNkKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDEgJiBzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMF0pCnNkKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDEgJiBzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMV0pCgp0LnRlc3Qoc3ViamVjdF9tZWFucyRydFtzdWJqZWN0X21lYW5zJGRpZmZpY3VsdHkgPT0gMSAmIHN1YmplY3RfbWVhbnMkbXVsdE51bSA9PSAwXSwKICAgICAgIHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDEgJiBzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMV0sIHBhaXJlZCA9IFRSVUUpCgojIEhhcmQsIDAgTXVsdC8xIE11bHQKbWVhbihzdWJqZWN0X21lYW5zJHJ0W3N1YmplY3RfbWVhbnMkZGlmZmljdWx0eSA9PSAzICYgc3ViamVjdF9tZWFucyRtdWx0TnVtID09IDBdKQptZWFuKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDMgJiBzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMV0pCnNkKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDMgJiBzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMF0pCnNkKHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDMgJiBzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMV0pCgp0LnRlc3Qoc3ViamVjdF9tZWFucyRydFtzdWJqZWN0X21lYW5zJGRpZmZpY3VsdHkgPT0gMyAmIHN1YmplY3RfbWVhbnMkbXVsdE51bSA9PSAwXSwKICAgICAgIHN1YmplY3RfbWVhbnMkcnRbc3ViamVjdF9tZWFucyRkaWZmaWN1bHR5ID09IDMgJiBzdWJqZWN0X21lYW5zJG11bHROdW0gPT0gMV0sIHBhaXJlZCA9IFRSVUUpCgojLS0tLS0tLS0tLS0tIwojIFBMT1QgICAgICAgIwojLS0tLS0tLS0tLS0tIwoKIyBGb3IgUlQKIyBTdGF0cyBTdW1tYXJ5CmRhdGFjIDwtIHN1bW1hcnlTRXdpdGhpbihkLCBtZWFzdXJldmFyPSJydCIsIHdpdGhpbnZhcnM9YygibXVsdE51bSIsImRpZmZpY3VsdHkiKSwgaWR2YXI9InN1YmplY3QiKQoKZ2dwbG90KGRhdGFjLCBhZXMoeD1kaWZmaWN1bHR5LCB5PXJ0LCBmaWxsPW11bHROdW0pKSArCiAgICBnZW9tX2Jhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSksIGNvbG91cj0iYmxhY2siLCBzdGF0PSJpZGVudGl0eSIpICsKICAgIGdlb21fZXJyb3JiYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpLCB3aWR0aD0uMjUsIGFlcyh5bWluPXJ0LWNpLCB5bWF4PXJ0K2NpKSkgKwogICAgY29vcmRfY2FydGVzaWFuKHlsaW09YygyLDQpKSArCiAgICBsYWJzKHkgPSAiVG90YWwgUlQgKHMpIiwgeCA9ICJEaWZmaWN1bHR5IChuZXQgdmFsdWUpIikgKwogICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiMSIgPSAiRWFzeSAoPjEpIiwgIjIiID0gIkRpZmZpY3VsdCAoMC41PDAuMjUpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjMiID0gIlZlcnkgRGlmZmljdWx0ICg8MC4yNSkiKSkgKwogICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMiw0LDAuMikpICsKICAgIHRoZW1lX2J3KCkgKwogICAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJOdW1iZXIgb2Zcbk11bHRpcGxpZXJzIikgCiAgICAjZ2d0aXRsZSgiUlQgdnMuIERpZmZpY3VsdHkgKyBOdW1iZXIgb2YgTXVsdGlwbGllcnMiKSAgCgojIEZvciBBY2N1cmFjeQojIFN0YXRzIFN1bW1hcnkKZGF0YWMgPC0gc3VtbWFyeVNFd2l0aGluKGQsIG1lYXN1cmV2YXI9ImNvcnJlY3QiLCB3aXRoaW52YXJzPWMoIm11bHROdW0iLCJkaWZmaWN1bHR5IiksIGlkdmFyPSJzdWJqZWN0IikKCmdncGxvdChkYXRhYywgYWVzKHg9ZGlmZmljdWx0eSwgeT1jb3JyZWN0LCBmaWxsPW11bHROdW0pKSArCiAgICBnZW9tX2Jhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSksIGNvbG91cj0iYmxhY2siLCBzdGF0PSJpZGVudGl0eSIpICsKICAgIGdlb21fZXJyb3JiYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpLCB3aWR0aD0uMjUsIGFlcyh5bWluPWNvcnJlY3QtY2ksIHltYXg9Y29ycmVjdCtjaSkpICsKICAgIGNvb3JkX2NhcnRlc2lhbih5bGltPWMoMC41LDEpKSArCiAgICBsYWJzKHkgPSAiQWNjdXJhY3kiLCB4ID0gIkRpZmZpY3VsdHkgKG5ldCB2YWx1ZSkiKSArCiAgICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIxIiA9ICJFYXN5ICg+MSkiLCAiMiIgPSAiRGlmZmljdWx0ICgwLjU8MC4yNSkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMyIgPSAiVmVyeSBEaWZmaWN1bHQgKDwwLjI1KSIpKSArICAgIAogICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwxLDAuMSkpICsKICAgIHRoZW1lX2J3KCkgKwogICAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJOdW1iZXIgb2Zcbk11bHRpcGxpZXJzIikgCiAgICAjZ2d0aXRsZSgiQWNjdXJhY3kgdnMuIERpZmZpY3VsdHkgKyBOdW1iZXIgb2YgTXVsdGlwbGllcnMiKSAgCmBgYAoKCiMgQU5PVkEKIyNBTk9WQSBvbiBkaWZmZXJlbmNlIGJldHdlZW4gKm11bHRpcGxpZXIqIGFuZCAqbm9uIG11bHRpcGxpZXIqIHRyaWFscyBSVAoKYGBge3IgYW5vdmEtbXVsdCwgZWNobz1GQUxTRX0KI2FkZCBtdWx0TnVtIGNvbHVtbgojdG90YWxfTV9jbGVhbjMkbXVsdE51bVt0b3RhbF9NX2NsZWFuMyRtdWx0MUhvdXNlPT0xICYgdG90YWxfTV9jbGVhbjMkbXVsdDJGYWNlPT0xXSA8LSAwCiN0b3RhbF9NX2NsZWFuMyRtdWx0TnVtW3RvdGFsX01fY2xlYW4zJG11bHQxSG91c2U+MSAmIHRvdGFsX01fY2xlYW4zJG11bHQyRmFjZT09MV0gPC0gMQojdG90YWxfTV9jbGVhbjMkbXVsdE51bVt0b3RhbF9NX2NsZWFuMyRtdWx0MUhvdXNlPT0xICYgdG90YWxfTV9jbGVhbjMkbXVsdDJGYWNlPjFdIDwtIDEKI3RvdGFsX01fY2xlYW4zJG11bHROdW1bdG90YWxfTV9jbGVhbjMkbXVsdDFIb3VzZT4xICYgdG90YWxfTV9jbGVhbjMkbXVsdDJGYWNlPjFdIDwtIDIKCgpkIDwtIHRvdGFsX01fY2xlYW4zCgpzdWJqZWN0X21lYW5zIDwtIGdyb3VwX2J5KGQsIHN1YmplY3QsIG11bHROdW0pICU+JQogIGRwbHlyOjpzdW1tYXJpemUocnQgPSBtZWFuKFJULCBuYS5ybSA9IFQpKQoKc3ViamVjdF9tZWFucyRzdWJqZWN0IDwtIGZhY3RvcihzdWJqZWN0X21lYW5zJHN1YmplY3QpCnN1YmplY3RfbWVhbnMkbXVsdE51bSA8LSBmYWN0b3Ioc3ViamVjdF9tZWFucyRtdWx0TnVtKQoKIyBEViA9IHJ0LCBmYWN0bwpyZXF1aXJlKG5sbWUpCmFtMiA8LSBsbWUocnQgfiBtdWx0TnVtLCByYW5kb20gPSB+MXxzdWJqZWN0L211bHROdW0sIGRhdGE9c3ViamVjdF9tZWFucykKc3VtbWFyeShhbTIpCmBgYAoKQmFzZWQgb24gdGhpcywgdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZWZmZWN0IChhcyBleHByZXNzZWQgdGhyb3VnaCBSVCkgaW4gaGF2aW5nIG9uZSBtdWx0aXBsaWVyLCBob3dldmVyIHRoZXJlICppcyogZm9yIGhhdmluZyB0d28uCgojIwoKYGBge3IgYW5vdmEtbXVsdDMsIGVjaG89RkFMU0V9CgpkIDwtIHRvdGFsX01fY2xlYW4zCgpkJHN1YmplY3QgPC0gZmFjdG9yKGQkc3ViamVjdCkKZCRtdWx0TnVtIDwtIGZhY3RvcihkJG11bHROdW0pCgojY29udmVydCBkIHRvIERhdGFGcmFtZQpkZiA8LSBkYXRhLmZyYW1lKHN1YmplY3Q9ZCRzdWJqZWN0LCBtdWx0TnVtPWQkbXVsdE51bSwgYWJzVmFsPWQkYWJzVmFsLCBydD1kJFJUKQoKI1RISVMgSVMgR0lWSU5HIEFOIEVSUk9SLCBDSEVDSyBXSVRIIExJWiEhCiNDZW5kcmkgc2l0ZTogaHR0cDovL3Jwc3ljaG9sb2dpc3QuY29tL3ItZ3VpZGUtbG9uZ2l0dWRpbmFsLWxtZS1sbWVyCiNhbTMgPC0gbG1lKHJ0IH4gbXVsdE51bSthYnNWYWwsIHJhbmRvbSA9ICwgZGF0YT1kZikKI3N1bW1hcnkoYW0zKQpgYGAKCkJhc2VkIG9uIHRoaXMsIHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGVmZmVjdCAoYXMgZXhwcmVzc2VkIHRocm91Z2ggUlQpIGluIGhhdmluZyBvbmUgbXVsdGlwbGllciwgaG93ZXZlciB0aGVyZSAqaXMqIGZvciBoYXZpbmcgdHdvLgoKIyMgRklYQVRJT04gRFVSQVRJT04KCmBgYHtyfQpsb2FkKCJEYXRhL1NfTV9LLlJkYXRhIikKZCA8LSBTX01fSwoKIyBGYWN0b3IgY29uZGl0aW9ucwpkJHN1YmplY3QgPC0gZmFjdG9yKGQkc3ViamVjdCkKCiMgRk9SIFQtVEVTVFMKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShkLCBzdWJqZWN0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKGZpcnN0Rml4ID0gbWVhbihmaXhEdXJbZml4TnVtID09IDFdKSwKICAgICAgICAgICAgICAgICAgIG1pZGRsZUZpeCA9IG1lYW4oZml4RHVyW2ZpeE51bSA+IDEgJiByZXZGaXhOdW0gPiAxXSksCiAgICAgICAgICAgICAgICAgICBmaW5hbEZpeCA9IG1lYW4oZml4RHVyW3JldkZpeE51bSA9PSAxXSkpCnN1YmplY3RfbWVhbnMKCiMgUGFpcmVkIFRUZXN0CiMgUlQKbWVhbihzdWJqZWN0X21lYW5zJGZpcnN0Rml4KQptZWFuKHN1YmplY3RfbWVhbnMkbWlkZGxlRml4KQptZWFuKHN1YmplY3RfbWVhbnMkZmluYWxGaXgpCnNkKHN1YmplY3RfbWVhbnMkZmlyc3RGaXgpCnNkKHN1YmplY3RfbWVhbnMkbWlkZGxlRml4KQpzZChzdWJqZWN0X21lYW5zJGZpbmFsRml4KQoKdC50ZXN0KHN1YmplY3RfbWVhbnMkbWlkZGxlRml4LAogICAgICAgc3ViamVjdF9tZWFucyRmaW5hbEZpeCwgcGFpcmVkID0gVFJVRSkKYGBgCgojI0xpbmVhciBNb2RlbHMgZm9yIERlcGVuZGVudCAoRml4ZWQpIEVmZmVjdHMgKG5vdCB0YWtpbmcgcmFuZG9tIGVmZmVjdHMgaW50byBhY2NvdW50KQoKYGBge3IgbG1zLTEsIGVjaG89RkFMU0V9CiNmaXQgYSBtb2RlbCB1c2luZyBob3VzZSB2YWx1ZSBhbmQgZmFjZSB2YWx1ZSBhcyBYLXZhcmlhYmxlcwptb2RlbDEgPC0gbG0oUlQgfiBmYWNlVmFsICsgaG91c2VWYWwsIGRhdGEgPSB0b3RhbF9NX2NsZWFuMykKc3VtbWFyeShtb2RlbDEpCgptb2RlbDIgPC0gbG0oUlQgfiBmYWNlVmFsKmhvdXNlVmFsLCBkYXRhID0gdG90YWxfTV9jbGVhbjMpCnN1bW1hcnkobW9kZWwyKQoKbW9kZWwzIDwtIGxtKFJUIH4gdG90YWxfMF9mYWNlICogdG90YWxfMV9ob3VzZSwgZGF0YSA9IHRvdGFsX01fY2xlYW4zKQpzdW1tYXJ5KG1vZGVsMykKCm1vZGVsNCA8LSBsbShSVCB+IG11bHQxSG91c2UqbXVsdDJGYWNlLCBkYXRhID0gdG90YWxfTV9jbGVhbjMpCnN1bW1hcnkobW9kZWw0KQoKbW9kZWw1IDwtIGxtKFJUIH4gKGZhY2VWYWwqbXVsdDJGYWNlKSAqIChob3VzZVZhbCptdWx0MUhvdXNlKSwgZGF0YSA9IHRvdGFsX01fY2xlYW4zKQpzdW1tYXJ5KG1vZGVsNSkKCiNERUxFVEUgY3JlYXRlIGZhY2UgdG90YWwgYW5kIGhvdXNlIHRvdGFsIGNvbHVtbnMKI0RFTEVURSB0b3RhbF9NX2NsZWFuMyRmYWNlVG90YWwgPC0gdG90YWxfTV9jbGVhbjMkZmFjZVZhbCp0b3RhbF9NX2NsZWFuMyRtdWx0MkZhY2UKI0RFTEVURSB0b3RhbF9NX2NsZWFuMyRob3VzZVRvdGFsIDwtIHRvdGFsX01fY2xlYW4zJGhvdXNlVmFsKnRvdGFsX01fY2xlYW4zJG11bHQxSG91c2UKCm1vZGVsNiA8LSBsbShSVCB+IGZhY2VUb3RhbCAqIGhvdXNlVG90YWwsIGRhdGEgPSB0b3RhbF9NX2NsZWFuMykKc3VtbWFyeShtb2RlbDYpCmBgYAoKIyNGaXJzdCBGaXhhdGlvbiBEdXJhdGlvbiB2cy4gRmlyc3QgSW1hZ2UgVG90YWwgVmFsdWUKYGBge3IgcGxvdC1maXJzdEZpeCwgZWNobz1GQUxTRX0KI2NyZWF0ZSBmaXJzdEZpeCBjb2x1bW4KZm9yKHggaW4gMTpucm93KHRvdGFsX01fY2xlYW4zKSl7CiAgdG90YWxfTV9jbGVhbjMkZmlyc3RGaXhbeF0gPC0gdG90YWxfTV9jbGVhbjMkZml4YXRpb25fdGltaW5nW3hdW1sxXV1bMV0KfQojY3JlYXRlIGZpcnN0SW1hZ2UgY29sdW1uCmZvcih4IGluIDE6bnJvdyh0b3RhbF9NX2NsZWFuMykpewogIHRvdGFsX01fY2xlYW4zJGZpcnN0SW1hZ2VbeF0gPC0gdG90YWxfTV9jbGVhbjMkaW1hZ2VTZXF1ZW5jZVt4XVtbMV1dWzFdCn0KI2NyZWF0ZSBmaXJzdFZhbCBjb2x1bW4gW2ZhY2UgaXMgMCwgaG91c2UgaXMgMV0KZm9yKHggaW4gMTpucm93KHRvdGFsX01fY2xlYW4zKSl7CiAgaWYgKHRvdGFsX01fY2xlYW4zJGZpcnN0SW1hZ2VbeF0gPT0gMCl7CiAgICB0b3RhbF9NX2NsZWFuMyRmaXJzdFZhbFt4XSA8LSB0b3RhbF9NX2NsZWFuMyRmYWNlVG90YWxbeF0KICB9CiAgaWYgKHRvdGFsX01fY2xlYW4zJGZpcnN0SW1hZ2VbeF0gPT0gMSl7CiAgICB0b3RhbF9NX2NsZWFuMyRmaXJzdFZhbFt4XSA8LSB0b3RhbF9NX2NsZWFuMyRob3VzZVRvdGFsW3hdCiAgfQp9Cgp0b3RhbF9NX2NsZWFuMyR0ZXN0IDwtIE5VTEwKCgojQW5kIGZvciBsYXRlciBsZXRzIGFsc28gY3JlYXRlIHNlY29uZEZpeCBhbmQgc2Vjb25kVmFsCiNzZWNvbmRGaXggY29sdW1uCmZvcih4IGluIDE6bnJvdyh0b3RhbF9NX2NsZWFuMykpewogIHRvdGFsX01fY2xlYW4zJHNlY29uZEZpeFt4XSA8LSB0b3RhbF9NX2NsZWFuMyRmaXhhdGlvbl90aW1pbmdbeF1bWzFdXVsyXQp9CiNjcmVhdGUgc2Vjb25kVmFsIGNvbHVtbiBbZmFjZSBpcyAwLCBob3VzZSBpcyAxIEJVVCBzaW5jZSBpdCBpcyB0aGUgc2Vjb25kIGltYWdlIGl0IGlzIHRoZSBvcHBvc2l0ZV0KZm9yKHggaW4gMTpucm93KHRvdGFsX01fY2xlYW4zKSl7CiAgaWYgKHRvdGFsX01fY2xlYW4zJGZpcnN0SW1hZ2VbeF0gPT0gMSl7CiAgICB0b3RhbF9NX2NsZWFuMyRzZWNvbmRWYWxbeF0gPC0gdG90YWxfTV9jbGVhbjMkZmFjZVRvdGFsW3hdCiAgfQogIGlmICh0b3RhbF9NX2NsZWFuMyRmaXJzdEltYWdlW3hdID09IDApewogICAgdG90YWxfTV9jbGVhbjMkc2Vjb25kVmFsW3hdIDwtIHRvdGFsX01fY2xlYW4zJGhvdXNlVG90YWxbeF0KICB9Cn0KCiNwbG90CmdncGxvdCh0b3RhbF9NX2NsZWFuMywgYWVzKHg9Zmlyc3RWYWwsIHk9Zmlyc3RGaXgpKSArCiAgZ2VvbV9wb2ludChzaGFwZT0xKSArICAgICMgVXNlIGhvbGxvdyBjaXJjbGVzCiAgZ2VvbV9zbW9vdGgoKSAgIyBBZGQgYSBsb2VzcyBzbW9vdGhlZCBmaXQgY3VydmUgd2l0aCBjb25maWRlbmNlIHJlZ2lvbgoKI01ha2UgMXN0IGFuZCAybmQgVmFscyBBYnNvbHV0ZQp0b3RhbF9NX2NsZWFuMyRhYnNGaXJzdFZhbCA9IGFicyh0b3RhbF9NX2NsZWFuMyRmaXJzdFZhbCkKdG90YWxfTV9jbGVhbjMkYWJzU2Vjb25kVmFsID0gYWJzKHRvdGFsX01fY2xlYW4zJHNlY29uZFZhbCkKCiNGaXJzdCBGaXgsIEZpcnN0IFZhbApnZ3Bsb3QodG90YWxfTV9jbGVhbjMsIGFlcyh4PWFic0ZpcnN0VmFsLCB5PWZpcnN0Rml4KSkgKwogIGdlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkKCnN1bW1hcnkobG0oZmlyc3RGaXh+YWJzRmlyc3RWYWwsIGRhdGE9dG90YWxfTV9jbGVhbjMpKQoKI1NlY29uZCBGaXgsIFNlY29uZCBWYWwKZ2dwbG90KHRvdGFsX01fY2xlYW4zLCBhZXMoeD1hYnNTZWNvbmRWYWwsIHk9c2Vjb25kRml4KSkgKwogIGdlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkKCnN1bW1hcnkobG0oc2Vjb25kRml4fmFic1NlY29uZFZhbCwgZGF0YT10b3RhbF9NX2NsZWFuMykpCgojRG9lcyB0aGUgZmlyc3QgdmFsdWUgYWZmZWN0IHRoZSBzZWNvbmQgZml4YXRpb24/CnN1bW1hcnkobG0oc2Vjb25kRml4fmFic0ZpcnN0VmFsLCBkYXRhPXRvdGFsX01fY2xlYW4zKSkKCiNEbyB0aGUgZmlyc3QgYW5kIHNlY29uZCB2YWx1ZXMgdG9nZXRoZXIgYWZmZWN0IHRoZSBzZWNvbmQgZml4YXRpb24/CnN1bW1hcnkobG0oc2Vjb25kRml4fmFic0ZpcnN0VmFsICsgYWJzU2Vjb25kVmFsLCBkYXRhPXRvdGFsX01fY2xlYW4zKSkKCiNJcyB0aGVyZSBhbiBpbnRlcmFjdGlvbiBiZXR3ZWVuIGZpcnN0IGFuZCBzZWNvbmQgdmFsIG9uIHRoZSBzZWNvbmQgZml4YXRpb24/CnN1bW1hcnkobG0oc2Vjb25kRml4fmFic0ZpcnN0VmFsKmFic1NlY29uZFZhbCwgZGF0YT10b3RhbF9NX2NsZWFuMykpCgpgYGAKCiMjRmlyc3QgRml4YXRpb24gRHVyYXRpb24gdnMuIEZpcnN0IE11bHQKYGBge3IgcGxvdC1maXJzdEZpeC1NdWx0LCBlY2hvPUZBTFNFfQoKI2NyZWF0ZSBmaXJzdE11bHQgY29sdW1uIFtmYWNlIGlzIDAsIGhvdXNlIGlzIDFdCmZvcih4IGluIDE6bnJvdyh0b3RhbF9NX2NsZWFuMykpewogIGlmICh0b3RhbF9NX2NsZWFuMyRmaXJzdEltYWdlW3hdID09IDApewogICAgdG90YWxfTV9jbGVhbjMkZmlyc3RNdWx0W3hdIDwtIHRvdGFsX01fY2xlYW4zJG11bHQyRmFjZVt4XQogIH0KICBpZiAodG90YWxfTV9jbGVhbjMkZmlyc3RJbWFnZVt4XSA9PSAxKXsKICAgIHRvdGFsX01fY2xlYW4zJGZpcnN0TXVsdFt4XSA8LSB0b3RhbF9NX2NsZWFuMyRtdWx0MUhvdXNlW3hdCiAgfQp9CgojY3JlYXRlIHNlY29uZE11bHQgY29sdW1uIChyZXZlcnNlIHRoZSBob3VzZS9mYWNlIHZhbHVlcykKZm9yKHggaW4gMTpucm93KHRvdGFsX01fY2xlYW4zKSl7CiAgaWYgKHRvdGFsX01fY2xlYW4zJGZpcnN0SW1hZ2VbeF0gPT0gMSl7CiAgICB0b3RhbF9NX2NsZWFuMyRzZWNvbmRNdWx0W3hdIDwtIHRvdGFsX01fY2xlYW4zJG11bHQyRmFjZVt4XQogIH0KICBpZiAodG90YWxfTV9jbGVhbjMkZmlyc3RJbWFnZVt4XSA9PSAwKXsKICAgIHRvdGFsX01fY2xlYW4zJHNlY29uZE11bHRbeF0gPC0gdG90YWxfTV9jbGVhbjMkbXVsdDFIb3VzZVt4XQogIH0KfQoKI0JBUiBQTE9UCnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkodG90YWxfTV9jbGVhbjMsIHN1YmplY3QsIGZpcnN0TXVsdCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShydCA9IG1lYW4oUlQsIG5hLnJtID0gVCkpCgojUExPVApiYXJwbG90IDwtIGdncGxvdChzdWJqZWN0X21lYW5zLCBhZXMoeCA9IGZpcnN0TXVsdCwgeSA9IHJ0KSkgKwogIHN0YXRfc3VtbWFyeSgKICAgIGdlb20gPSAiYmFyIiwKICAgIGZ1bi55ID0gIm1lYW4iLAogICAgY29sID0gImJsYWNrIiwKICAgIGZpbGwgPSAiZ3JheTcwIgogICkgKwogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaCA9IDAsIHcgPSAwLjIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgbWF4KGQkUlQsIG5hLnJtID0gVCkpLAogICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBjKDAsIDApKQpiYXJwbG90CgojU2l6ZSBvZiBmaXJzdCBtdWx0IFNJRyBvbiBSVD8Kc3VtbWFyeShsbShsb2dSVH5maXJzdE11bHQsIGRhdGE9dG90YWxfTV9jbGVhbjMpKQpgYGAKCiNBUFJJTCAyNDogTkVXIEFOQUxZU0VTIAoKIyNNaXhlZCBNb2RlbHMKCiMjI0ZPUiBTVEFSVEVSUzogRG9lcyBzdW1tZWQgdmFsdWUgYWZmZWN0IFJUICh1c2luZyBsb2cgUlQpPwpgYGB7ciBtaXgtbW9kZWwtcnQtMDEsIGVjaG89RkFMU0V9CnJ0Lm51bGwgPSBsbWVyKGxvZ1JUIH4gMSArICgxfHN1YmplY3QpLCBkYXRhID0gdG90YWxfTV9jbGVhbjMsIFJFTUwgPSBGQUxTRSkKcnQubW9kZWwxID0gbG1lcihsb2dSVCB+IHN1bW1lZFZhbCArICgxfHN1YmplY3QpLCBkYXRhPXRvdGFsX01fY2xlYW4zLCBSRU1MPUZBTFNFKQoKYW5vdmEocnQubnVsbCxydC5tb2RlbDEpCmBgYAoKUGVyaGFwcyB1bnN1cnByaXNpbmdseSBiYXNlZCBvbiB3aGF0IHdlIHBsb3R0ZWQgYmVmb3JlLCBzdW1tZWQgdmFsdWUgaGFzIGEgaGlnaGx5IHNpZ25pZmljYW50IGVmZmVjdCBvbiByZWFjdGlvbiB0aW1lIChjb250cm9sbGluZyBmb3IgcmFuZG9tIGVmZmVjdHMgb2Ygc3ViamVjdHMpLgoKCiMjI1N1bW1lZCBWYWx1ZSBhcyB0aGUgaW5kaXZpZHVhbCBUT1RBTCB2YWx1ZXMgKHRoZSB2YWx1ZSB4IG11bHRpcGxpZXIpIG9mIHRoZSBGQUNFIGFuZCBIT1VTRQpgYGB7ciBtaXgtbW9kZWwtcnQtMDIsIGVjaG89RkFMU0V9CnJ0Lm51bGwgPSBsbWVyKGxvZ1JUIH4gMSArICgxfHN1YmplY3QpLCBkYXRhID0gdG90YWxfTV9jbGVhbjMsIFJFTUwgPSBGQUxTRSkKcnQubW9kZWwyID0gbG1lcihsb2dSVCB+IGZhY2VUb3RhbCArIGhvdXNlVG90YWwgKyAoMXxzdWJqZWN0KSwgZGF0YT10b3RhbF9NX2NsZWFuMywgUkVNTD1GQUxTRSkKCnN1bW1hcnkocnQubW9kZWwyKQphbm92YShydC5udWxsLHJ0Lm1vZGVsMikKYW5vdmEocnQubW9kZWwxLCBydC5tb2RlbDIpCmBgYAoKQmFzZWQgb24gdGhpcyB0aGVyZSBpcyBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgYmV0d2VlbiBtZWFuIFJUIGFuZCBydC5tb2RlbDIgYXMgd2VsbCBhcyBiZXR3ZWVuIHJ0Lm1vZGVsMiBhbmQgcnQubW9kZWwxCgoKIyMjV2hhdCBhYm91dCBpbnRlcmFjdGlvbiBiZXR3ZWVuIGZhY2VUb3RhbCBhbmQgaG91c2VUb3RhbD8KYGBge3IgbWl4LW1vZGVsLXJ0LTAzLCBlY2hvPUZBTFNFfQpydC5tb2RlbDMgPSBsbWVyKGxvZ1JUIH4gZmFjZVRvdGFsICogaG91c2VUb3RhbCArICgxfHN1YmplY3QpLCBkYXRhPXRvdGFsX01fY2xlYW4zLCBSRU1MPUZBTFNFKQoKc3VtbWFyeShydC5tb2RlbDMpCmFub3ZhKHJ0Lm1vZGVsMiwgcnQubW9kZWwzKQpgYGAKClNvIHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gYmV3dGVlbiB0aGUgdG90YWwgaG91c2UgdmFsdWUgYW5kIHRoZSB0b3RhbCBmYWNlIHZhbHVlIChhcyBleHBlY3RlZCkuCgoKIyMjQW5kIHRoZW4gd2hhdCBpZiB3ZSBsb29rIGF0IHRoZSBjb21wb25lbnRzICh2YWx1ZSAqIG11bHRpcGxpZXIpIG9mIHRoZSBUb3RhbCBGYWNlIGFuZCBUb3RhbCBIb3VzZSBWYWx1ZT8gCmBgYHtyIG1peC1tb2RlbC1ydC0wNCwgZWNobz1GQUxTRX0KcnQubW9kZWw0ID0gbG1lcihsb2dSVCB+IGZhY2VWYWwgKiBtdWx0MkZhY2UgKiBob3VzZVZhbCAqIG11bHQxSG91c2UgKyAoMXxzdWJqZWN0KSwgZGF0YT10b3RhbF9NX2NsZWFuMywgUkVNTD1GQUxTRSkKCnN1bW1hcnkocnQubW9kZWw0KQphbm92YShydC5tb2RlbDMsIHJ0Lm1vZGVsNCkKYGBgCkFnYWluLCBiYXNlZCBvbiB0aGUgYW5vdmEgYW5hbHlzaXMgdGhlcmUgc2VlbXMgdG8gYmUgc2lnbmlmaWNhbmNlIGluIHRoZSBpbnRlcmFjdGlvbnMgYmV0d2VlbiB0aGUgdmFsdWVzIGFuZCB0aGUgbXVsdGlwbGllcnMuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCiNSVCBQTE9UUwojI1Bsb3QgUlQgcmFuZG9tIGVmZmVjdHMgb2Ygc3ViamVjdHMKYGBge3IgcGxvdC1ydC1yYW5kRWZmZWN0LCBlY2hvPUZBTFNFfQojUlQgdnMuIFN1bW1lZCBWYWx1ZQpsaWJyYXJ5KG1lclRvb2xzKSAgICAgICAjIyBmb3IgbG1lcigpLCBzbGVlcHN0dWR5CmZpdCA8LSBsbWVyKGxvZ1JUIH4gc3VtbWVkVmFsICsgKHN1bW1lZFZhbHxzdWJqZWN0KSwgdG90YWxfTV9jbGVhbjMpCnJhbmRvbXMgPC0gUkVzaW0oZml0LCBuLnNpbXMgPSA1MDApCgpwbG90UkVzaW0ocmFuZG9tcykKYGBgCgojI1Bsb3QgUlQgd2l0aCBtdWx0aXBsZSBsaW5lcyAoYXZlcmFnZSBvZiBlYWNoIHN1YmplY3RzIGxpbmUpCiogbXVsdGlwbGllciB0cmlhbHMKKiBmbGlwIHRyaWFscwoqIG5vbiBmbGlwIHRyaWFscwoqIG5vbiBtdWx0IHRyaWFscwoKYGBge3IgcGxvdC1ydC1tdWx0bGluZXMwMSwgZWNobz1GQUxTRX0KI1JUIHZzLiBTdW1tZWQgVmFsdWUKZ2dwbG90KCkgKwogIGdlb21fc21vb3RoKGFlcyh4PXN1bW1lZFZhbCwgeT1sb2dSVCwgZ3JvdXAgPSBmYWN0b3IobXVsdE51bSksIGNvbG91ciA9IGZhY3RvcihtdWx0TnVtKSksIHRvdGFsX01fY2xlYW4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWxvZ1JULCBjb2xvdXIgPSAiZmxpcCIpLCBzdWJzZXQodG90YWxfTV9jbGVhbjMsIGZsaXA9PTEpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0zLCAzKSkgICsKICAjZ2VvbV9wb2ludChzaGFwZT0xKSArICAgICMgVXNlIGhvbGxvdyBjaXJjbGVzCiAgZ2VvbV9zbW9vdGgoKSAgIyBBZGQgYSBsb2VzcyBzbW9vdGhlZCBmaXQgY3VydmUgd2l0aCBjb25maWRlbmNlIHJlZ2lvbgoKI2NyZWF0ZSBtdWx0bnVtIGFzIGZhY3Rvcgp0b3RhbF9NX2NsZWFuMyRtdWx0TnVtRiA9IGZhY3Rvcih0b3RhbF9NX2NsZWFuMyRtdWx0TnVtKQojVGVzdCBmb3IgU0lHCnN1bW1hcnkobG0obG9nUlR+c3VtbWVkVmFsICsgbXVsdE51bUYgKyBmbGlwLCB0b3RhbF9NX2NsZWFuMykpCmBgYAoKTm90ZSB0aGF0IHdpdGggdGhlIGZsaXAgdHJpYWxzIHRoZSBzdW1tZWQgdmFsdWVzIHJhbmdlZCBmcm9tIC0wLjYgdG8gMC42LgoKIyNQbG90IEFjY3VyYWN5ICglIGNvcnJlY3QpIHdpdGggbXVsdGlwbGUgbGluZXMgKGF2ZXJhZ2Ugb2YgZWFjaCBzdWJqZWN0cyBsaW5lKQoqIG11bHRpcGxpZXIgdHJpYWxzCiogZmxpcCB0cmlhbHMKKiBub24gZmxpcCB0cmlhbHMKKiBub24gbXVsdCB0cmlhbHMKCmBgYHtyIHBsb3QtcnQtbXVsdGxpbmVzMDIsIGVjaG89RkFMU0V9CiNSVCB2cy4gU3VtbWVkIFZhbHVlCmdncGxvdCgpICsKICBnZW9tX3Ntb290aChhZXMoeD1zdW1tZWRWYWwsIHk9Y29ycmVjdCwgZ3JvdXAgPSBmYWN0b3IobXVsdE51bSksIGNvbG91ciA9IGZhY3RvcihtdWx0TnVtKSksIHRvdGFsX01fY2xlYW4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWNvcnJlY3QsIGNvbG91ciA9ICJmbGlwIiksIHN1YnNldCh0b3RhbF9NX2NsZWFuMywgZmxpcD09MSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTMsIDMpKSAgKwogICNnZW9tX3BvaW50KHNoYXBlPTEpICsgICAgIyBVc2UgaG9sbG93IGNpcmNsZXMKICBnZW9tX3Ntb290aCgpICAjIEFkZCBhIGxvZXNzIHNtb290aGVkIGZpdCBjdXJ2ZSB3aXRoIGNvbmZpZGVuY2UgcmVnaW9uCmBgYAoKIyMjU2FtZSBQbG90IGJ1dCBqdXN0IGZvciAiRGlmZmljdWx0IiBjaG9pY2VzCmBgYHtyIHBsb3QtcnQtbXVsdGxpbmVzMDksIGVjaG89RkFMU0V9CiNSVCB2cy4gU3VtbWVkIFZhbHVlCmdncGxvdCgpICsKICBnZW9tX3Ntb290aChhZXMoeD1zdW1tZWRWYWwsIHk9Y29ycmVjdCwgZ3JvdXAgPSBmYWN0b3IobXVsdE51bSksIGNvbG91ciA9IGZhY3RvcihtdWx0TnVtKSksIHRvdGFsX01fY2xlYW4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWNvcnJlY3QsIGNvbG91ciA9ICJmbGlwIiksIHN1YnNldCh0b3RhbF9NX2NsZWFuMywgZmxpcD09MSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLS41LCAuNSkpICArCiAgI2dlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkgICMgQWRkIGEgbG9lc3Mgc21vb3RoZWQgZml0IGN1cnZlIHdpdGggY29uZmlkZW5jZSByZWdpb24KCm1lYW4odG90YWxfTV9jbGVhbjMkUlRbdG90YWxfTV9jbGVhbjMkbXVsdE51bT09MF0pCm1lYW4odG90YWxfTV9jbGVhbjMkUlRbdG90YWxfTV9jbGVhbjMkbXVsdE51bT09MV0pCm1lYW4odG90YWxfTV9jbGVhbjMkUlRbdG90YWxfTV9jbGVhbjMkbXVsdE51bT09Ml0pCgoKZCA8LSB0b3RhbF9NX2NsZWFuMwojMSBtdWx0IGFuZCAyIG11bHQgc2lnLiBkaWZmZXJlbnQgZm9yIFN1bW1tZWRWYWwgaW50ZXJ2YWwgKC0wLjUsIDAuNSkKdC50ZXN0KGQkY29ycmVjdFtkJG11bHROdW0gPT0gMCAmIGQkc3VtbWVkVmFsPi0wLjUgJiBkJHN1bW1lZFZhbDwwLjVdLCBkJGNvcnJlY3RbZCRtdWx0TnVtPT0xICYgZCRzdW1tZWRWYWw+LTAuNSAmIGQkc3VtbWVkVmFsPDAuNV0pCgpgYGAKCiMjI1JUIGZvciBkaWZmaWN1bHQgY2hvaWNlcyBieSBtdWx0TnVtCmBgYHtyIHBsb3QtcnQtbXVsdGxpbmVzMTksIGVjaG89RkFMU0V9CiNSVCB2cy4gU3VtbWVkIFZhbHVlCmdncGxvdCgpICsKICBnZW9tX3Ntb290aChhZXMoeD1zdW1tZWRWYWwsIHk9UlQsIGdyb3VwID0gZmFjdG9yKG11bHROdW0pLCBjb2xvdXIgPSBmYWN0b3IobXVsdE51bSkpLCB0b3RhbF9NX2NsZWFuMykgKwogIGdlb21fc21vb3RoKGFlcyh4PXN1bW1lZFZhbCwgeT1SVCwgY29sb3VyID0gImZsaXAiKSwgc3Vic2V0KHRvdGFsX01fY2xlYW4zLCBmbGlwPT0xKSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMSwgMSkpICArCiAgI2dlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkgICMgQWRkIGEgbG9lc3Mgc21vb3RoZWQgZml0IGN1cnZlIHdpdGggY29uZmlkZW5jZSByZWdpb24KCmQgPC0gdG90YWxfTV9jbGVhbjMKIzEgbXVsdCBhbmQgMiBtdWx0IHNpZy4gZGlmZmVyZW50IGZvciBTdW1tbWVkVmFsIGludGVydmFsICgtMC41LCAwLjUpIFlFUwp0LnRlc3QoZCRSVFtkJG11bHROdW0gPT0gMCAmIGQkc3VtbWVkVmFsPi0wLjUgJiBkJHN1bW1lZFZhbDwwLjVdLCBkJFJUW2QkbXVsdE51bT09MSAmIGQkc3VtbWVkVmFsPi0wLjUgJiBkJHN1bW1lZFZhbDwwLjVdKQoKIzEgbXVsdCBhbmQgMiBtdWx0IHNpZy4gZGlmZmVyZW50IGZvciBTdW1tbWVkVmFsIGludGVydmFsICgtMiwgLTAuNSkgTk8KdC50ZXN0KGQkUlRbZCRtdWx0TnVtID09IDAgJiBkJHN1bW1lZFZhbDwgKC0wLjUpICYgZCRzdW1tZWRWYWw+LTJdLCBkJFJUW2QkbXVsdE51bT09MSAmIGQkc3VtbWVkVmFsPCgtMC41KSAmIGQkc3VtbWVkVmFsPi0yXSkKCiMxIG11bHQgYW5kIDIgbXVsdCBzaWcuIGRpZmZlcmVudCBmb3IgU3VtbW1lZFZhbCBpbnRlcnZhbCAoMC41LDIpIE5PCnQudGVzdChkJFJUW2QkbXVsdE51bSA9PSAwICYgZCRzdW1tZWRWYWw+MC41ICYgZCRzdW1tZWRWYWw8Ml0sIGQkUlRbZCRtdWx0TnVtPT0xICYgZCRzdW1tZWRWYWw+MC41ICYgZCRzdW1tZWRWYWw8Ml0pCgpgYGAKCgojI0NIT0lDRSBDVVJWRQolIGFjY2VwdGFuY2UgKHNpbnVzb2lkKQogICAgLXNpbnVzb2lkIGZvciBub24gbXVsdC9tdWx0L2ZsaXAKICAgIAojI1ZhbHVlIG9mIGZpcnN0IGl0ZW0gdnMuIEZpcnN0IGl0ZW0gZml4YXRpb24gdGltZQoqIG5vIG11bHQKKiAyeCBtdWx0CiogM3ggbXVsdApgYGB7ciBwbG90LWZpcnN0dmFsLW11bHRsaW5lczAxLCBlY2hvPUZBTFNFfQojUlQgdnMuIFN1bW1lZCBWYWx1ZQpnZ3Bsb3QoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHg9Zmlyc3RWYWwsIHk9Zmlyc3RGaXgsIGdyb3VwID0gZmFjdG9yKGZpcnN0TXVsdCksIGNvbG91ciA9IGZhY3RvcihmaXJzdE11bHQpKSwgdG90YWxfTV9jbGVhbjMpICsKICAjZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWxvZ1JULCBjb2xvdXIgPSAiZmxpcCIpLCBzdWJzZXQodG90YWxfTV9jbGVhbjMsIGZsaXA9PTEpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0zLCAzKSkgICsKICAjZ2VvbV9wb2ludChzaGFwZT0xKSArICAgICMgVXNlIGhvbGxvdyBjaXJjbGVzCiAgZ2VvbV9zbW9vdGgoKSAgIyBBZGQgYSBsb2VzcyBzbW9vdGhlZCBmaXQgY3VydmUgd2l0aCBjb25maWRlbmNlIHJlZ2lvbgpgYGAKCiMjVmFsdWUgb2Ygc2Vjb25kIGl0ZW0gdnMuIFNlY29uZCBpdGVtIGZpeGF0aW9uIHRpbWUKKiBubyBtdWx0CiogMnggbXVsdAoqIDN4IG11bHQKCmBgYHtyIHBsb3Qtc2Vjb25kVmFsLW11bHRsaW5lczAxLCBlY2hvPUZBTFNFfQojUlQgdnMuIFN1bW1lZCBWYWx1ZQpnZ3Bsb3QoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHg9c2Vjb25kVmFsLCB5PXNlY29uZEZpeCwgZ3JvdXAgPSBmYWN0b3Ioc2Vjb25kTXVsdCksIGNvbG91ciA9IGZhY3RvcihzZWNvbmRNdWx0KSksIHRvdGFsX01fY2xlYW4zKSArCiAgI2dlb21fc21vb3RoKGFlcyh4PXN1bW1lZFZhbCwgeT1sb2dSVCwgY29sb3VyID0gImZsaXAiKSwgc3Vic2V0KHRvdGFsX01fY2xlYW4zLCBmbGlwPT0xKSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMywgMykpICArCiAgI2dlb21fcG9pbnQoc2hhcGU9MSkgKyAgICAjIFVzZSBob2xsb3cgY2lyY2xlcwogIGdlb21fc21vb3RoKCkgICMgQWRkIGEgbG9lc3Mgc21vb3RoZWQgZml0IGN1cnZlIHdpdGggY29uZmlkZW5jZSByZWdpb24KYGBgCgojI1N1bW1lZCB2YWx1ZSB2cyBzZWNvbmQgaXRlbSBmaXhhdGlvbiB0aW1lCgpgYGB7ciBwbG90LXN1bW1lZFZhbEZpeC1tdWx0bGluZXMwMSwgZWNobz1GQUxTRX0KI1JUIHZzLiBTdW1tZWQgVmFsdWUKZ2dwbG90KCkgKwogIGdlb21fc21vb3RoKGFlcyh4PXN1bW1lZFZhbCwgeT1zZWNvbmRGaXgsIGdyb3VwID0gZmFjdG9yKG11bHROdW0pLCBjb2xvdXIgPSBmYWN0b3IobXVsdE51bSkpLCB0b3RhbF9NX2NsZWFuMykgKwogICNnZW9tX3Ntb290aChhZXMoeD1zdW1tZWRWYWwsIHk9bG9nUlQsIGNvbG91ciA9ICJmbGlwIiksIHN1YnNldCh0b3RhbF9NX2NsZWFuMywgZmxpcD09MSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTMsIDMpKSAgKwogICNnZW9tX3BvaW50KHNoYXBlPTEpICsgICAgIyBVc2UgaG9sbG93IGNpcmNsZXMKICBnZW9tX3Ntb290aCgpICAjIEFkZCBhIGxvZXNzIHNtb290aGVkIGZpdCBjdXJ2ZSB3aXRoIGNvbmZpZGVuY2UgcmVnaW9uCmBgYAoKIyNOdW1iZXIgb2Ygc3dhcHMKKiBiYXNlZCBvbiBzdW1tZWQgdmFsdWUKCmBgYHtyIHBsb3Qtc3dhcENvdW50LXN1bW1lZFZhbDIsIGVjaG89RkFMU0V9CiNSVCB2cy4gU3VtbWVkIFZhbHVlCmdncGxvdCgpICsKICBnZW9tX3Ntb290aChhZXMoeD1zdW1tZWRWYWwsIHk9c3dhcENvdW50LCBncm91cCA9IGZhY3RvcihtdWx0TnVtKSwgY29sb3VyID0gZmFjdG9yKG11bHROdW0pKSwgdG90YWxfTV9jbGVhbjMpICsKICAjZ2VvbV9zbW9vdGgoYWVzKHg9c3VtbWVkVmFsLCB5PWxvZ1JULCBjb2xvdXIgPSAiZmxpcCIpLCBzdWJzZXQodG90YWxfTV9jbGVhbjMsIGZsaXA9PTEpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0zLCAzKSkgICsKICAjZ2VvbV9wb2ludChzaGFwZT0xKSArICAgICMgVXNlIGhvbGxvdyBjaXJjbGVzCiAgZ2VvbV9zbW9vdGgoKSAgIyBBZGQgYSBsb2VzcyBzbW9vdGhlZCBmaXQgY3VydmUgd2l0aCBjb25maWRlbmNlIHJlZ2lvbgpgYGAKCiogYmFzZWQgb24gYW1iaWd1aXR5IG9mIGluZGl2aWR1YWwgc3RpbXVsaSAoaWUuIGNsb3NlciB0byB6ZXJvKQogICAgLXN0aW11bHVzIGxlZnQgaGFzIGFtYmlndWl0eSBYLCBzdGltdWx1cyByaWdodCBoYXMgYW1iaWd1aXR5IFksIHN1bW1lZCB2YWx1ZSBoYXMgYW1iaWd1aXR5IFoKICAgIC1ob3cgbXVjaCBkb2VzIGluZGl2aWR1YWwgYW1iaWd1aXR5IHZzIGNvbWJpbmVkIGFtYmlndWl0eSBhZmZlY3QgUlQvc3dhcHMKCmBgYHtyIHBsb3Qtc3dhcENvdW50LXN1bW1lZFZhbCwgZWNobz1GQUxTRX0KI1JUIHZzLiBTdW1tZWQgVmFsdWUKZ2dwbG90KCkgKwogIGdlb21fc21vb3RoKGFlcyh4PWZhY2VWYWwsIHk9c3dhcENvdW50LCBjb2xvdXIgPSAiZmFjZVZhbCIpLCB0b3RhbF9NX2NsZWFuMykgKwogIGdlb21fc21vb3RoKGFlcyh4PWhvdXNlVmFsLCB5PXN3YXBDb3VudCwgY29sb3VyID0gImhvdXNlVmFsIiksIHN1YnNldCh0b3RhbF9NX2NsZWFuMywgZmxpcD09MSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTEsIDEpKSAgKwogIGdndGl0bGUoIkltYWdlIHN3YXBzIHZzLiBBbWJpZ3VpdHkgb2YgU3RpbXVsdXMiKSArCiAgbGFicyh4ID0gIlZhbHVlIikKICAjZ2VvbV9wb2ludChzaGFwZT0xKSArICAgICMgVXNlIGhvbGxvdyBjaXJjbGVzCiAgZ2VvbV9zbW9vdGgoKSAgIyBBZGQgYSBsb2VzcyBzbW9vdGhlZCBmaXQgY3VydmUgd2l0aCBjb25maWRlbmNlIHJlZ2lvbgpgYGAKCiMjU0FMSUVOQ1kgVEVTVDogTWVhbiBGaXhhdGlvbiBIb3VzZSB2LiBGYWNlCmBgYHtyIHBvc05lZy1iYXJwbG90MTExLCBlY2hvPUZBTFNFfQojVCBURVNUIEhPVVNFIHYgRkFDRSBGSVggVElNRQptZWFuKHRvdGFsX01fY2xlYW4zJHRvdGFsXzFfaG91c2UpCm1lYW4odG90YWxfTV9jbGVhbjMkdG90YWxfMF9mYWNlKQp0LnRlc3QodG90YWxfTV9jbGVhbjMkdG90YWxfMV9ob3VzZSwgdG90YWxfTV9jbGVhbjMkdG90YWxfMF9mYWNlKQojUExPVCBUSElTCgojIyMjIyMjIyMjIyMKIyBBQlMgRkFDRSBWQUxVRSBHUkVBVEVSCiMjIyMjIyMjIyMjIwoKI0ZJWCBUSU1FIE9OIEZBQ0UKbWVhbih0b3RhbF9NX2NsZWFuMyR0b3RhbF8wX2ZhY2VbYWJzKHRvdGFsX01fY2xlYW4zJGZhY2VWYWwpID4gYWJzKHRvdGFsX01fY2xlYW4zJGhvdXNlVmFsKV0pCiNGSVggVElNRSBPTiBIT1VTRQptZWFuKHRvdGFsX01fY2xlYW4zJHRvdGFsXzFfaG91c2VbYWJzKHRvdGFsX01fY2xlYW4zJGZhY2VWYWwpID4gYWJzKHRvdGFsX01fY2xlYW4zJGhvdXNlVmFsKV0pCiNUVEVTVAp0LnRlc3QoKHRvdGFsX01fY2xlYW4zJHRvdGFsXzBfZmFjZVthYnModG90YWxfTV9jbGVhbjMkZmFjZVZhbCkgPiBhYnModG90YWxfTV9jbGVhbjMkaG91c2VWYWwpXSksICh0b3RhbF9NX2NsZWFuMyR0b3RhbF8xX2hvdXNlW2Ficyh0b3RhbF9NX2NsZWFuMyRmYWNlVmFsKSA+IGFicyh0b3RhbF9NX2NsZWFuMyRob3VzZVZhbCldKSkKCiMjIyMjIyMjIyMjIwojIEFCUyBIT1VTRSBWQUxVRSBHUkVBVEVSCiMjIyMjIyMjIyMjIwoKI0ZJWCBUSU1FIE9OIEhPVVNFCm1lYW4odG90YWxfTV9jbGVhbjMkdG90YWxfMV9ob3VzZVthYnModG90YWxfTV9jbGVhbjMkZmFjZVZhbCkgPCBhYnModG90YWxfTV9jbGVhbjMkaG91c2VWYWwpXSkKI0ZJWCBUSU1FIE9OIEZBQ0UKbWVhbih0b3RhbF9NX2NsZWFuMyR0b3RhbF8wX2ZhY2VbYWJzKHRvdGFsX01fY2xlYW4zJGZhY2VWYWwpIDwgYWJzKHRvdGFsX01fY2xlYW4zJGhvdXNlVmFsKV0pCiNUVEVTVAp0LnRlc3QoKHRvdGFsX01fY2xlYW4zJHRvdGFsXzFfaG91c2VbYWJzKHRvdGFsX01fY2xlYW4zJGZhY2VWYWwpIDwgYWJzKHRvdGFsX01fY2xlYW4zJGhvdXNlVmFsKV0pLCAodG90YWxfTV9jbGVhbjMkdG90YWxfMF9mYWNlW2Ficyh0b3RhbF9NX2NsZWFuMyRmYWNlVmFsKSA8IGFicyh0b3RhbF9NX2NsZWFuMyRob3VzZVZhbCldKSkKCiMjIFdlIGxvb2sgbG9uZ2VyIGF0IHRoZSBpdGVtIHdpdGggbG93ZXIgYWJzb2x1dGUgdmFsdWUhIQogICMjIFdoYXQgYWJvdXQgY2FzZSB3aGVyZSBvbmUgaXMgcG9zaXRpdmUgdGhlIG90aGVyIG5lZ2F0aXZlCgojIyMjIyMjIyMjIyMKIyBUSEUgREVDSURFUiBGSVhBVElPTgojIyMjIyMjIyMjIyMKIyBEbyB3ZSBsb29rIGxvbmdlciBpbiB0cmlhbHMgd2l0aCBvcHBvc2l0ZSBzaWduZWQgc3RpbXVsaSBhdCB0aGUgaXRlbSB3aXRoIGhpZ2hlciBhYnMgdmFsPwoKI01ha2UgRmFjdG9yIENvbHVtbiBmb3IgRkFDRS9IT1VTRSAoMC8xKSBwcCwgbm4sIHBuLCBucAp0b3RhbF9NX2NsZWFuMyRwb3NOZWcgPC0gInBwIgp0b3RhbF9NX2NsZWFuMyRwb3NOZWdbdG90YWxfTV9jbGVhbjMkZmFjZVZhbD4wICYgdG90YWxfTV9jbGVhbjMkaG91c2VWYWw8MF0gPC0gInBuIgp0b3RhbF9NX2NsZWFuMyRwb3NOZWdbdG90YWxfTV9jbGVhbjMkZmFjZVZhbDwwICYgdG90YWxfTV9jbGVhbjMkaG91c2VWYWw+MF0gPC0gIm5wIgp0b3RhbF9NX2NsZWFuMyRwb3NOZWdbdG90YWxfTV9jbGVhbjMkZmFjZVZhbDwwICYgdG90YWxfTV9jbGVhbjMkaG91c2VWYWw8MF0gPC0gIm5uIgoKdG90YWxfTV9jbGVhbjMkcG9zTmVnIDwtIGZhY3Rvcih0b3RhbF9NX2NsZWFuMyRwb3NOZWcpCgojTWFrZSBDb2x1bW4gZm9yIEZpeGF0aW9uIEJpYXMKdG90YWxfTV9jbGVhbjMkZml4QmlhcyA8LSB0b3RhbF9NX2NsZWFuMyR0b3RhbF8wX2ZhY2UgLSB0b3RhbF9NX2NsZWFuMyR0b3RhbF8xX2hvdXNlCgpkIDwtIHRvdGFsX01fY2xlYW4zCgpnZ3Bsb3QoZCkgKwogIGdlb21fYmFyKGFlcyhwb3NOZWcsIGZpeEJpYXMpLAogICAgICAgICAgIHBvc2l0aW9uID0gImRvZGdlIiwgc3RhdCA9ICJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIpCmBgYApQZW9wbGUgbG9va2VkIGF0IEhPVVNFUyBsb25nZXIuIE1vcmUgc2FsaWVudD8gT3IgbW9yZSBhbWJpZ3VvdXM/CgojI0ZJTkFMIEZJWEFUSU9OOiBUaWVkIHRvIFZhbHVlPwpgYGB7ciBwb3NOZWctYmFycGxvdDE5LCBlY2hvPUZBTFNFfQoKI0FERCBDb2x1bW4gZm9yIHRvdGFsIEZBQ0UgYW5kIEhPVVNFIFZBTFMKdG90YWxfTV9jbGVhbjMkdG90YWxGYWNlVmFsIDwtIHRvdGFsX01fY2xlYW4zJGZhY2VWYWwgKiB0b3RhbF9NX2NsZWFuMyRtdWx0MkZhY2UKdG90YWxfTV9jbGVhbjMkdG90YWxIb3VzZVZhbCA8LSB0b3RhbF9NX2NsZWFuMyRob3VzZVZhbCAqIHRvdGFsX01fY2xlYW4zJG11bHQxSG91c2UKCmxpYnJhcnkobmxtZSkKZCA8LSB0b3RhbF9NX2NsZWFuMwoKIyMjIyMjIwojIE5PIE1VTFQsIEpVU1QgVkFMVUUKIyMjIyMjIwoKI0xBU1QgSU1BR0UgPSBGQUNFICgwKQptZWFuKGQkZmFjZVZhbFtkJGxhc3RJbWFnZT09MF0pCm1lYW4oZCRob3VzZVZhbFtkJGxhc3RJbWFnZT09MF0pCiMjIEZhY2VzICt2ZSwgSG91c2VzIC12ZQoKI0xBU1QgSU1BR0UgPSBIT1VTRSAoMSkKbWVhbihkJGZhY2VWYWxbZCRsYXN0SW1hZ2U9PTFdKQptZWFuKGQkaG91c2VWYWxbZCRsYXN0SW1hZ2U9PTFdKQojIyBIb3VzZXMgK3ZlLCBGYWNlcyAtdmUKCiMjIyMjIyMKIyBNVUxUICogVkFMVUUKIyMjIyMjIwoKI0xBU1QgSU1BR0UgPSBGQUNFICgwKQptZWFuKGQkdG90YWxGYWNlVmFsW2QkbGFzdEltYWdlPT0wXSkKbWVhbihkJHRvdGFsSG91c2VWYWxbZCRsYXN0SW1hZ2U9PTBdKQojIyBGYWNlcyArdmUsIEhvdXNlcyAtdmUKCiNMQVNUIElNQUdFID0gSE9VU0UgKDEpCm1lYW4oZCR0b3RhbEZhY2VWYWxbZCRsYXN0SW1hZ2U9PTFdKQptZWFuKGQkdG90YWxIb3VzZVZhbFtkJGxhc3RJbWFnZT09MV0pCiMjIEhvdXNlcyArdmUsIEZhY2VzIC12ZQoKCiNNYWtlIExhc3QgaW1hZ2UgRmFjdG9yCmQkbGFzdEltYWdlRiA8LSBmYWN0b3IoZCRsYXN0SW1hZ2UpCiNTaWcgRWZmZWN0PwpzdW1tYXJ5KGxtZShmYWNlVmFsIH4gbGFzdEltYWdlRiwgcmFuZG9tID0gfjF8c3ViamVjdCwgZGF0YT1kKSkKCiNUZW5kIHRvIGxvb2sgbGFzdCBhdCBpbWFnZSB0aGF0IGhhcyBoaWdoZXIvcG9zaXR2ZSB2YWx1ZQoKZ2dwbG90KGQsIGFlcyh4PWZhY2VWYWwsIHk9aG91c2VWYWwpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyPWxhc3RJbWFnZUYpKQpgYGAKCgoKIyMjQXJlIHBlb3BsZSB0YWtpbmcgbG9uZ2VyIGZvciBmbGlwIHRyaWFscyBhZnRlciBhY2NvdW50aW5nIGZvciBmYWN0IHRoYXQgZmxpcCB0cmlhbHMgQUxXQVlTIGhhdmUgbXVsdGlwbGllcnMgKGFuZCBub24tZmxpcCB0cmlhbHMgZG9u4oCZdCkgIAoKVGhpcyBpcyBub3QgY3VycmVudGx5IHdvcmtpbmcKCmBgYHtyIG1peC1tb2RlbC0wMSwgZWNobz1GQUxTRX0KCiNsbWVyKHJ0IH4gbXVsdE51bSArIGZsaXAgKyAoMXxzdWJqZWN0KSArIChtdWx0TnVtfHN1YmplY3QpICsgKGZsaXB8c3ViamVjdCksIGRhdGEgPSB0b3RhbF9NX2NsZWFuMykKYGBgCgojI1F1ZXN0aW9ubmFpcmUgRGF0YQoKIyMjIFBsb3R0aW5nIEdQQSB2cy4gRWFybmluZ3MgKHVuZmlsdGVyZWQgZGF0YSk6CgpgYGB7ciBSVF9FYXJuaW5ncy1HUEEtdW5maWx0ZXJlZCwgZWNobz1GQUxTRX0KI1NlbGVjdCBkYXRhZnJhbWUgdG8gdXNlCmQgPC0gU19NX3JhdwoKI2ltcG9ydCBRdWVzdGlvbm5haXJlIGRhdGEKc2V0d2QoIn4vRHJvcGJveC9QSEQvQ0VORFJJL1Byb2plY3QvQ29kZS9MYWJTaGFyZWRGb2xkZXIvTUFERTAxL0NPREUvR0lUL0JlaGF2aW9yX0FuYWx5c2lzIikKUXVlc3QuZGYgPC0gcmVhZC5jc3YoImNzdl9maWxlcy9RdWVzdGlvbm5haXJlMDFfUmVzdWx0cy5jc3YiKQpRdWVzdC5kZiA8LSBRdWVzdC5kZlsoUXVlc3QuZGYkc3R1ZHlfdmVyc2lvbiA9PSAyKSwgXQoKI21lYW4gUlQgYW5kIEZpbmFsIGVhcm5pbmdzIGJ5IHN1YmplY3QKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShkLCBzdWJqZWN0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHJ0ID0gbWVhbihSVCwgbmEucm0gPSBUKSwgZmluYWxFYXJuaW5ncyA9IG1lYW4oZmluYWxFYXJuaW5ncywgbmEucm0gPSBUKSkKCnN1YmplY3RfaW5mbyA8LSBncm91cF9ieShRdWVzdC5kZiwgc3ViamVjdCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShncGEgPSBtZWFuKEdQQSwgbmEucm0gPSBUKSwgZWZmb3J0ID0gbWVhbihFZmZvcnQsIG5hLnJtID0gVCksIGd1ZXNzID0gbWVhbihHdWVzc2luZywgbmEucm0gPSBUKSwgY29tcGFyYXRpdmUgPSBtZWFuKENvbXBhcmVkX3RvX290aGVycywgbmEucm0gPSBUKSkKCnN1YmplY3RfbWVhbnMgPC0gbWVyZ2Uoc3ViamVjdF9tZWFucywgc3ViamVjdF9pbmZvLCBieSA9ICJzdWJqZWN0IikKc3ViamVjdF9tZWFucwoKI0JBU0VEIE9OIEdQQQpzdWJqZWN0X21lYW5zX2dwYSA8LSBuYS5vbWl0KHN1YmplY3RfbWVhbnMpCnBsb3QoeCA9IHN1YmplY3RfbWVhbnNfZ3BhJGdwYSwgeSA9IHN1YmplY3RfbWVhbnNfZ3BhJGZpbmFsRWFybmluZ3MsCiAgICAgbWFpbiA9ICJQZXJmb3JtYW5jZSBhcyByZWxhdGVkIHRvIEdQQSIsCiAgICAgeWxhYiA9ICJGaW5hbCBFYXJuaW5ncyIsCiAgICAgeGxhYiA9ICJHUEEiKQphYmxpbmUobG0oc3ViamVjdF9tZWFuc19ncGEkZmluYWxFYXJuaW5nc35zdWJqZWN0X21lYW5zX2dwYSRncGEpLCBjb2w9InJlZCIpICMgcmVncmVzc2lvbiBsaW5lICh5fngpIApsaW5lcyhsb3dlc3Moc3ViamVjdF9tZWFuc19ncGEkZ3BhLHN1YmplY3RfbWVhbnNfZ3BhJGZpbmFsRWFybmluZ3MpLCBjb2w9ImJsdWUiKSAjIGxvd2VzcyBsaW5lICh4LHkpCgojVEVTVCBGT1IgU0lHLgpzdW1tYXJ5KGxtKGZpbmFsRWFybmluZ3N+Z3BhLCBzdWJqZWN0X21lYW5zX2dwYSkpCgojQkFTRUQgT04gRUZGT1JUCnBsb3QoeCA9IHN1YmplY3RfbWVhbnMkZWZmb3J0LCB5ID0gc3ViamVjdF9tZWFucyRmaW5hbEVhcm5pbmdzLAogICAgIG1haW4gPSAiUGVyZm9ybWFuY2UgYXMgcmVsYXRlZCB0byBwZXJjZWl2ZWQgZWZmb3J0IiwKICAgICB5bGFiID0gIkZpbmFsIEVhcm5pbmdzIiwKICAgICB4bGFiID0gIlJlcG9ydGVkIEVmZm9ydCIpCmFibGluZShsbShzdWJqZWN0X21lYW5zJGZpbmFsRWFybmluZ3N+c3ViamVjdF9tZWFucyRlZmZvcnQpLCBjb2w9InJlZCIpICMgcmVncmVzc2lvbiBsaW5lICh5fngpIApsaW5lcyhsb3dlc3Moc3ViamVjdF9tZWFucyRlZmZvcnQsc3ViamVjdF9tZWFucyRmaW5hbEVhcm5pbmdzKSwgY29sPSJibHVlIikgIyBsb3dlc3MgbGluZSAoeCx5KQoKI1Rlc3QgZm9yIFNpZ25pZmljYW5jZQpzdW1tYXJ5KGxtKGZpbmFsRWFybmluZ3N+ZWZmb3J0LCBzdWJqZWN0X21lYW5zKSkKCiNCQVNFRCBPTiBHVUVTU0lORwpwbG90KHggPSBzdWJqZWN0X21lYW5zJGd1ZXNzLCB5ID0gc3ViamVjdF9tZWFucyRmaW5hbEVhcm5pbmdzLAogICAgIG1haW4gPSAiUGVyZm9ybWFuY2UgYXMgcmVsYXRlZCB0byBndWVzcyBmcmVxdWVuY3kiLAogICAgIHlsYWIgPSAiRmluYWwgRWFybmluZ3MiLAogICAgIHhsYWIgPSAiUmVwb3J0ZWQgR3Vlc3MgRnJlcXVlbmN5IikKYWJsaW5lKGxtKHN1YmplY3RfbWVhbnMkZmluYWxFYXJuaW5nc35zdWJqZWN0X21lYW5zJGd1ZXNzKSwgY29sPSJyZWQiKSAjIHJlZ3Jlc3Npb24gbGluZSAoeX54KSAKbGluZXMobG93ZXNzKHN1YmplY3RfbWVhbnMkZ3Vlc3Msc3ViamVjdF9tZWFucyRmaW5hbEVhcm5pbmdzKSwgY29sPSJibHVlIikgIyBsb3dlc3MgbGluZSAoeCx5KQoKI1RFU1QgRk9SIFNJR05JRklDQU5DRQpzdW1tYXJ5KGxtKGZpbmFsRWFybmluZ3N+Z3Vlc3MsIHN1YmplY3RfbWVhbnMpKQoKI0JBU0VEIE9OIENPTVBBUklTT04KcGxvdCh4ID0gc3ViamVjdF9tZWFucyRjb21wYXJhdGl2ZSwgeSA9IHN1YmplY3RfbWVhbnMkZmluYWxFYXJuaW5ncywKICAgICBtYWluID0gIlBlcmZvcm1hbmNlIHZzLiBDb21wYXJhcnRpdmUgU2VsZi1Bc3Nlc3NtZW50IiwKICAgICB5bGFiID0gIkZpbmFsIEVhcm5pbmdzIiwKICAgICB4bGFiID0gIlJlcG9ydGVkIENvbXBhcmF0aXZlIFBlcmZvcm1hbmNlIikKYWJsaW5lKGxtKHN1YmplY3RfbWVhbnMkZmluYWxFYXJuaW5nc35zdWJqZWN0X21lYW5zJGNvbXBhcmF0aXZlKSwgY29sPSJyZWQiKSAjIHJlZ3Jlc3Npb24gbGluZSAoeX54KSAKbGluZXMobG93ZXNzKHN1YmplY3RfbWVhbnMkY29tcGFyYXRpdmUsc3ViamVjdF9tZWFucyRmaW5hbEVhcm5pbmdzKSwgY29sPSJibHVlIikgIyBsb3dlc3MgbGluZSAoeCx5KQoKI1RFU1QgRk9SIFNJR05JRklDQU5DRSBjb21wYXJlZCB0byBvdGhlcnMKc3VtbWFyeShsbShmaW5hbEVhcm5pbmdzfmNvbXBhcmF0aXZlLCBzdWJqZWN0X21lYW5zKSkKI3dpdGgoc3ViamVjdF9tZWFucywgY29yLnRlc3QoZmluYWxFYXJuaW5ncyxjb21wYXJhdGl2ZSkpCgpzdW1tYXJ5KGxtKGZpbmFsRWFybmluZ3N+ZWZmb3J0LCBzdWJqZWN0X21lYW5zKSkKc3VtbWFyeShsbShmaW5hbEVhcm5pbmdzfmVmZm9ydCtjb21wYXJhdGl2ZSwgc3ViamVjdF9tZWFucykpCnN1bW1hcnkobG0oZmluYWxFYXJuaW5nc35lZmZvcnQqY29tcGFyYXRpdmUqZ3Vlc3MsIHN1YmplY3RfbWVhbnMpKQpgYGAKCiMjU3Ryb29wIERhdGEKCmBgYHtyIFN0cm9vcF8wMSwgZWNobz1GQUxTRX0KI2ZpbmQgc3ViamVjdCBhY2NydWFjeSAodW5jbGVhbmVkKQphY2N1cmFjeSA9IHRhcHBseShTdHJvb3AuZGYuZnVsbCRSZXNwb25zZS5jb3JyPT0xLCBTdHJvb3AuZGYuZnVsbCRzdWJqZWN0LCBtZWFuKQoKI2hpc3RzIG9mIHJ0IGJhc2VkIG9uIGNvbmdydWVudCBhbmQgaW5jb25ncnVlbnQgdHJpYWxzCmhpc3QoU3Ryb29wLmRmLmNsZWFuW1N0cm9vcC5kZi5jbGVhbiRjb25ncnVlbnQ9PTEsIF0kUmVzcG9uc2UucnQsCiAgIGNvbD1yZ2IoMSwwLDAsMC41KSwgYnJlYWtzPXNlcSgwLDIuNSwwLjA1KSwgeWxpbT1jKDAsMjAwKSwgeGxhYj0iUlQiLCBtYWluID0gIlJUIHZzIEZyZXF1ZW5jeSIpCmhpc3QoU3Ryb29wLmRmLmNsZWFuW1N0cm9vcC5kZi5jbGVhbiRjb25ncnVlbnQ9PTAsIF0kUmVzcG9uc2UucnQsCiAgIGNvbD1yZ2IoMCwwLDEsMC41KSwgYnJlYWtzPXNlcSgwLDIuNSwwLjA1KSwgeWxpbT1jKDAsMjAwKSwgYWRkPVQpCmxlZ2VuZCgidG9wcmlnaHQiLCBjKCJDb25ncnVlbnQiLCAiSW5jb25ncnVlbnQiKSwgZmlsbD1jKHJnYigxLDAsMCwwLjUpLCByZ2IoMCwwLDEsMC41KSkpCgojY3JlYXRlIHJ0cyBmb3IgZWFjaCBzdWJqZWN0IGJhc2VkIG9uIGNvbmdydWVudC9pbmNvbmdydWVudApydF9ieV9jb25kaXRpb24gPSB0YXBwbHkoU3Ryb29wLmRmLmNsZWFuJFJlc3BvbnNlLnJ0LCBsaXN0KFN0cm9vcC5kZi5jbGVhbiRzdWJqZWN0LCBTdHJvb3AuZGYuY2xlYW4kY29uZ3J1ZW50KSwgbWVhbikKI2NvbnZlcnQgdG8gZGF0YSBmcmFtZQpydF9ieV9jb25kaXRpb24gPSBhcy5kYXRhLmZyYW1lKHJ0X2J5X2NvbmRpdGlvbikgCm5hbWVzKHJ0X2J5X2NvbmRpdGlvbikgPSBjKCJpbmNvbmdydWVudCIsICJjb25ncnVlbnQiKQoKI2dldCBtZWFucwptZWFuX3J0cyA9IGFwcGx5KHJ0X2J5X2NvbmRpdGlvbiwgMiwgbWVhbikKI2dldCBTRQpuc3ViaiA9IGxlbmd0aChydF9ieV9jb25kaXRpb25bLDFdKQpzZHMgPSBhcHBseShydF9ieV9jb25kaXRpb24sIDIsIHNkKQpzZSA9IHNkcy9zcXJ0KG5zdWJqKQoKI0NSRUFURSBBIEJBUlBMT1QKeD1iYXJwbG90KG1lYW5fcnRzLCBjb2w9YyhyZ2IoMSwwLDAsMC41KSxyZ2IoMCwwLDEsMC41KSksbWFpbj0iUlQKICAgaW4gZWFjaCBjb25kaXRpb24iLHhsYWI9IkNvbmRpdGlvbiIseWxhYj0iUlQiLHlsaW0gPSBjKDAsMS4zKSkKc2VnbWVudHMoeCwgbWVhbl9ydHMtc2UsIHgsIG1lYW5fcnRzK3NlKQoKI1Rlc3QgZm9yIFNJRwpTdHJvb3AuZGYuY2xlYW4kY29uZ3J1ZW50ID0gYXMuZmFjdG9yKFN0cm9vcC5kZi5jbGVhbiRjb25ncnVlbnQpCnRhYmxlKFN0cm9vcC5kZi5jbGVhbiRjb25ncnVlbnQpCnN1bW1hcnkobG0oUmVzcG9uc2UucnR+Y29uZ3J1ZW50LCBTdHJvb3AuZGYuY2xlYW4pKQpgYGAKCiMjI0FOT1ZBIGZvciBzaWduaWZpY2FuY2UKCmBgYHtyIGFub3ZhLXN0cm9vcCwgZWNobz1UUlVFfQojcmVmb3JtYXQgRGF0YSBGcmFtZQpmb3VuZCA9IHdoaWNoKHJ0X2J5X2NvbmRpdGlvbiE9LTk5OSxhcnIuaW5kPVQpCnJ0QU5PVkEgPSBkYXRhLmZyYW1lKGNiaW5kKGZvdW5kLHJ0X2J5X2NvbmRpdGlvbltmb3VuZF0pKQpuYW1lcyhydEFOT1ZBKSA9IGMoJ3N1YmonLCdjb25kJywncnQnKQoKcnRBTk9WQSRzdWJqID0gZmFjdG9yKHJ0QU5PVkEkc3ViaikKcnRBTk9WQSRjb25kID0gZmFjdG9yKHJ0QU5PVkEkY29uZCkKCm15YW92ID0gYW92KHJ0QU5PVkEkcnR+cnRBTk9WQSRjb25kK0Vycm9yKHJ0QU5PVkEkc3ViaikpCnN1bW1hcnkobXlhb3YpCmBgYAoKIyMjVC1UZXN0CgpgYGB7ciB0dGVzdC1zdHJvb3AsIGVjaG89VFJVRX0KI3JlZm9ybWF0IERhdGEgRnJhbWUKdC50ZXN0KHJ0X2J5X2NvbmRpdGlvbiRjb25ncnVlbnQscnRfYnlfY29uZGl0aW9uJGluY29uZ3J1ZW50LHBhaXJlZD1ULG11PTAsYWx0ZXJuYXRpdmU9InR3by5zaWRlZCIsdmFyLmVxdWFsPVQpCgpgYGAKCkJhc2VkIG9uIEFub3ZhL1RUZXN0IHNlZW1zIGxpa2UgdGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlLgoKYGBge3Igc3Ryb29wLXBlcmZvcm1hbmNlLCBlY2hvPVRSVUV9CiNTZWxlY3QgZGF0YWZyYW1lIHRvIHVzZQpkIDwtIFN0cm9vcC5kZi5jbGVhbgoKI21lYW4gUlQgYW5kIEZpbmFsIGVhcm5pbmdzIGJ5IHN1YmplY3QKU3Ryb29wLnBlcmZvcm1hbmNlIDwtIGdyb3VwX2J5KGQsIHN1YmplY3QpICU+JQogIGRwbHlyOjpzdW1tYXJpemUocnQgPSBtZWFuKFJlc3BvbnNlLnJ0LCBuYS5ybSA9IFQpLCBhY2N1cmFjeSA9IG1lYW4oUmVzcG9uc2UuY29yciwgbmEucm0gPSBUKSkKU3Ryb29wLnBlcmZvcm1hbmNlJHBlcmZvcm1hbmNlID0gU3Ryb29wLnBlcmZvcm1hbmNlJHJ0ICogMS9TdHJvb3AucGVyZm9ybWFuY2UkYWNjdXJhY3kKI2ludmVydCBzbyBiaWdnZXIgbnVuYmVycyBhcmUgYmV0dGVyClN0cm9vcC5wZXJmb3JtYW5jZSRwZXJmb3JtYW5jZSA9IDEvU3Ryb29wLnBlcmZvcm1hbmNlJHBlcmZvcm1hbmNlCmBgYAoKCiMjU3Ryb29wIFBlcmZvcm1hbmNlIHZzLiBUYXNrIFBlcmZvcm1hbmNlCiMjI3ZzIEVhcm5pbmdzCgpgYGB7ciBzdHJvb3AtZG90cGxvdCwgZWNobz1GQUxTRX0KI1NlbGVjdCBkYXRhZnJhbWUgdG8gdXNlCmQgPC0gdG90YWxfTV9jbGVhbjMKCiNtZWFuIFJUIGFuZCBGaW5hbCBlYXJuaW5ncyBieSBzdWJqZWN0CnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShydCA9IG1lYW4oUlQsIG5hLnJtID0gVCksIGZpbmFsRWFybmluZ3MgPSBtZWFuKGZpbmFsRWFybmluZ3MsIG5hLnJtID0gVCkpCnN1YmplY3RfbWVhbnMKCnBsb3QoeCA9IFN0cm9vcC5wZXJmb3JtYW5jZSRwZXJmb3JtYW5jZSwgeSA9IHN1YmplY3RfbWVhbnMkZmluYWxFYXJuaW5ncywKICAgICBtYWluID0gIlN0cm9vcCBQZXJmb3JtYW5jZSB2cyBGaW5hbCBFYXJuaW5ncyIsCiAgICAgeWxhYiA9ICJGaW5hbCBFYXJuaW5ncyIsCiAgICAgeGxhYiA9ICJTdHJvb3AgUGVyZm9ybWFuY2UiKQphYmxpbmUobG0oc3ViamVjdF9tZWFucyRmaW5hbEVhcm5pbmdzflN0cm9vcC5wZXJmb3JtYW5jZSRwZXJmb3JtYW5jZSksIGNvbD0icmVkIikgIyByZWdyZXNzaW9uIGxpbmUgKHl+eCkgCmxpbmVzKGxvd2VzcyhTdHJvb3AucGVyZm9ybWFuY2UkcGVyZm9ybWFuY2UsIHN1YmplY3RfbWVhbnMkZmluYWxFYXJuaW5ncyksIGNvbD0iYmx1ZSIpICMgbG93ZXNzIGxpbmUgKHgseSkKYGBgCgojIyN2cyBBY2N1cmFjeQoKYGBge3Igc3Ryb29wLWRvdHBsb3QyLCBlY2hvPUZBTFNFfQojU2VsZWN0IGRhdGFmcmFtZSB0byB1c2UKZCA8LSB0b3RhbF9NX2NsZWFuMwoKI21lYW4gUlQgYW5kIEZpbmFsIGVhcm5pbmdzIGJ5IHN1YmplY3QKc3ViamVjdF9tZWFucyA8LSBncm91cF9ieShkLCBzdWJqZWN0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHJ0ID0gbWVhbihSVCwgbmEucm0gPSBUKSwgYWNjdXJhY3kgPSBtZWFuKGNvcnJlY3QsIG5hLnJtID0gVCkpCnN1YmplY3RfbWVhbnMKCnBsb3QoeCA9IFN0cm9vcC5wZXJmb3JtYW5jZSRwZXJmb3JtYW5jZSwgeSA9IHN1YmplY3RfbWVhbnMkYWNjdXJhY3ksCiAgICAgbWFpbiA9ICJTdHJvb3AgUGVyZm9ybWFuY2UgdnMgQWNjdXJhY3kiLAogICAgIHlsYWIgPSAiQWNjdXJhY3kiLAogICAgIHhsYWIgPSAiU3Ryb29wIFBlcmZvcm1hbmNlIikKYWJsaW5lKGxtKHN1YmplY3RfbWVhbnMkYWNjdXJhY3l+U3Ryb29wLnBlcmZvcm1hbmNlJHBlcmZvcm1hbmNlKSwgY29sPSJyZWQiKSAjIHJlZ3Jlc3Npb24gbGluZSAoeX54KSAKbGluZXMobG93ZXNzKFN0cm9vcC5wZXJmb3JtYW5jZSRwZXJmb3JtYW5jZSwgc3ViamVjdF9tZWFucyRhY2N1cmFjeSksIGNvbD0iYmx1ZSIpICMgbG93ZXNzIGxpbmUgKHgseSkKCiNUZXN0IGZvciBTSUcKc3VtbWFyeShsbShzdWJqZWN0X21lYW5zJGFjY3VyYWN5flN0cm9vcC5wZXJmb3JtYW5jZSRwZXJmb3JtYW5jZSkpCmBgYAoKIyMjdnMgUlQKCmBgYHtyIHN0cm9vcC1kb3RwbG90MywgZWNobz1GQUxTRX0KI1NlbGVjdCBkYXRhZnJhbWUgdG8gdXNlCmQgPC0gdG90YWxfTV9jbGVhbjMKCiNtZWFuIFJUIGFuZCBGaW5hbCBlYXJuaW5ncyBieSBzdWJqZWN0CnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShydCA9IG1lYW4oUlQsIG5hLnJtID0gVCksIGZpbmFsRWFybmluZ3MgPSBtZWFuKGZpbmFsRWFybmluZ3MsIG5hLnJtID0gVCkpCnN1YmplY3RfbWVhbnMKCnBsb3QoeCA9IFN0cm9vcC5wZXJmb3JtYW5jZSRwZXJmb3JtYW5jZSwgeSA9IHN1YmplY3RfbWVhbnMkcnQsCiAgICAgbWFpbiA9ICJTdHJvb3AgUGVyZm9ybWFuY2UgdnMgUlQiLAogICAgIHlsYWIgPSAiUlQiLAogICAgIHhsYWIgPSAiU3Ryb29wIFBlcmZvcm1hbmNlIikKYWJsaW5lKGxtKHN1YmplY3RfbWVhbnMkcnR+U3Ryb29wLnBlcmZvcm1hbmNlJHBlcmZvcm1hbmNlKSwgY29sPSJyZWQiKSAjIHJlZ3Jlc3Npb24gbGluZSAoeX54KSAKbGluZXMobG93ZXNzKFN0cm9vcC5wZXJmb3JtYW5jZSRwZXJmb3JtYW5jZSwgc3ViamVjdF9tZWFucyRydCksIGNvbD0iYmx1ZSIpICMgbG93ZXNzIGxpbmUgKHgseSkKCiNUZXN0IGZvciBTSUcKc3VtbWFyeShsbShzdWJqZWN0X21lYW5zJHJ0flN0cm9vcC5wZXJmb3JtYW5jZSRwZXJmb3JtYW5jZSkpCmBgYAoKIyNFRkZFQ1QgU0laRQojIyNDb2hlbidzIEQKCmBgYHtyIGNvaGVucy1kLTAxLCBlY2hvPVRSVUV9CiNTZWxlY3QgZGF0YWZyYW1lIHRvIHVzZQpkIDwtIHRvdGFsX01fY2xlYW4zCgojbWVhbiBSVCBhbmQgRmluYWwgZWFybmluZ3MgYnkgc3ViamVjdApydF9tdWx0cyA8LSBncm91cF9ieShkLCBzdWJqZWN0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKG11bHRfMCA9IG1lYW4oUlRbbXVsdE51bT09MF0pLCBtdWx0XzEgPSBtZWFuKFJUW211bHROdW09PTFdLCBuYS5ybSA9IFQpLCBtdWx0XzIgPSBtZWFuKFJUW211bHROdW09PTJdLCBuYS5ybT1UKSkKcnRfbXVsdHMKCmxpYnJhcnkobHNyKQpjb2hlbnNEKHJ0X211bHRzJG11bHRfMCwgcnRfbXVsdHMkbXVsdF8xKQpjb2hlbnNEKHJ0X211bHRzJG11bHRfMCwgcnRfbXVsdHMkbXVsdF8yKQpgYGAKCgojI01FQU5TCiMjI0xpc3Qgb2YgTWVhbiBSVHMgZm9yIE11bHRzCgpgYGB7ciBtdWx0bWVhbnMtMDEsIGVjaG89VFJVRX0KI1NlbGVjdCBkYXRhZnJhbWUgdG8gdXNlCmQgPC0gdG90YWxfTV9jbGVhbjMKCiNtZWFuIFJUIGRlcGVuZGluZyBvbiBtdWx0aXBsaWVyIGNvbWJpbmF0aW9uCmZvcihpIGluIDE6Myl7CiAgZm9yKGogaW4gMTozKXsKICAgIG0gPC0gbWVhbihkJFJUW2QkbXVsdDFIb3VzZT09aSAmIGQkbXVsdDJGYWNlPT1qXSkKICAgIGNhdChzcHJpbnRmKCJIb3VzZSBNdWx0ID0gJXMgYW5kIEZhY2UgTXVsdCA9ICVzXG4iLCBpLCBqKSkKICAgIGNhdChzcHJpbnRmKCJNZWFuOiAlZlxuXG4iLCBtKSkKICB9Cn0KYGBgCgoKIyNNT1JFIE1JWEVEIEVGRkVDVFMgU1RVRkYKCiMjIwpgYGB7ciByYW5lZl8wMSwgZWNobz1GQUxTRX0KI0ZST006IGh0dHBzOi8vYmlvbG9neWZvcmZ1bi53b3JkcHJlc3MuY29tLzIwMTcvMDQvMDMvaW50ZXJwcmV0aW5nLXJhbmRvbS1lZmZlY3RzLWluLWxpbmVhci1taXhlZC1lZmZlY3QtbW9kZWxzLwoKbGlicmFyeShyZXNoYXBlMikKbV9hdmcgPC0gbG1lcihSVCB+IDEgKyAoMXxzdWJqZWN0KSwgdG90YWxfTV9jbGVhbjMpCnJhbmVmKG1fYXZnKQoKI3RvIGdldCB0aGUgZml0dGVkIGF2ZXJhZ2UgcmVhY3Rpb24gdGltZSBwZXIgc3ViamVjdApyZWFjdGlvbl9zdWJqZWN0IDwtIGZpeGVmKG1fYXZnKSArIHJhbmVmKG1fYXZnKSRzdWJqZWN0CnJlYWN0aW9uX3N1YmplY3Qkc3ViamVjdDwtcm93bmFtZXMocmVhY3Rpb25fc3ViamVjdCkKbmFtZXMocmVhY3Rpb25fc3ViamVjdClbMV08LSJJbnRlcmNlcHQiCnJlYWN0aW9uX3N1YmplY3QgPC0gcmVhY3Rpb25fc3ViamVjdFssYygyLDEpXQojcGxvdApnZ3Bsb3QocmVhY3Rpb25fc3ViamVjdCxhZXMoeD1zdWJqZWN0LHk9SW50ZXJjZXB0KSkrZ2VvbV9wb2ludCgpCmBgYAoKIyMjU2ltdWxhdGUgUlRzIGJhc2VkIG9uIGRhdGEKYGBge3IgcmFuZWZfMDIsIGVjaG89RkFMU0V9CiNUaGlzIGxpbmUgY3JlYXRlIGEgZGF0YWZyYW1lIGZvciAxOCBoeXBvdGhldGljYWwgbmV3IHN1YmplY3RzCiN0YWtpbmcgdGhlIGVzdGltYXRlZCBzdGFuZGFyZCBkZXZpYXRpb24gcmVwb3J0ZWQgaW4KI3N1bW1hcnkobV9hdmcpIGFuZCB0YWtlIFNVQkpFQ1QgU0QKbmV3X3N1YmplY3QgPC0gZGF0YS5mcmFtZShzdWJqZWN0ID0gYXMuY2hhcmFjdGVyKDUwOjc0KSwKICBJbnRlcmNlcHQ9IGZpeGVmKG1fYXZnKStybm9ybSgyNSwwLDEuMDA2KSxTdGF0dXM9IlNpbXVsYXRlZCIpCnJlYWN0aW9uX3N1YmplY3QkU3RhdHVzIDwtICJPYnNlcnZlZCIKcmVhY3Rpb25fc3ViamVjdCA8LSByYmluZChyZWFjdGlvbl9zdWJqZWN0LG5ld19zdWJqZWN0KQojbmV3IHBsb3QKZ2dwbG90KHJlYWN0aW9uX3N1YmplY3QsYWVzKHg9c3ViamVjdCx5PUludGVyY2VwdCxjb2xvcj1TdGF0dXMpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IGZpeGVmKG1fYXZnKVsxXSxsaW5ld2lkdGg9MS41KSkKYGBgCgojI0FicyBWYWwgdnMuIFJUCiMjI1N1YmplY3QgTGV2ZWwKCmBgYHtyIHN1YmplY3QtbGV2ZWwtZ3JhcGhzLCBlY2hvPUZBTFNFfQojdGhlIG5leHQgbGluZSBwdXQgYWxsIHRoZSBlc3RpbWF0ZWQgaW50ZXJjZXB0IGFuZCBzbG9wZSBwZXIgc3ViamVjdCBpbnRvIGEgZGF0YWZyYW1lCiNTdW1tZWQgdmFsIGFzIEFic29sdXRlIChkaXN0YW5jZSBmcm9tIGFtYmlndWl0eSkKCiNtX3NscCA8LSBsbWVyKGxvZ1JUIH4gYWJzVmFsICsgKDF8c3ViamVjdCkgKyAoYWJzVmFsfHN1YmplY3QpLCB0b3RhbF9NX2NsZWFuMywgUkVNTCA9IEZBTFNFKQpyZW1vdmUoc3ViamVjdF9tZWFucykKbV9zbHAgPC0gbG1lcihsb2dSVCB+IGFic1ZhbCArIChhYnNWYWx8c3ViamVjdCksIHRvdGFsX01fY2xlYW4zKQoKI3N1YmplY3QgZGlmZmVyZW5jZXMgaW4gaW50ZXJjZXB0IGFuZCBzbG9wZSBpbnRvIGRhdGFmcmFtZQpkZiA8LSBkYXRhLmZyYW1lKGNvZWYobV9zbHApW1sxXV0pCgojSnVzdCBzb21lIHJlbmFtaW5nIHRpZHlpbmcKZGYkc3ViamVjdDwtcm93bmFtZXMoZGYpCm5hbWVzKGRmKVsxXTwtImludGVyY2VwdCIKZGYgPC0gZGZbLGMoMywxLDIpXQoKI2JpbiBSVHMKZCA8LSB0b3RhbF9NX2NsZWFuMwpkJHZhbEJpbiA9IGN1dChkJGFic1ZhbCwgYygtSW5mLCAwLjUsIDEsIDEuNSwgMiwgMi41LCAzLCBJbmYpLCBsYWJlbHMgPSAxOjcpCgpzdWJqZWN0X21lYW5zIDwtIGdyb3VwX2J5KGQsIHN1YmplY3QsIHZhbEJpbikgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShydCA9IG1lYW4obG9nUlQsIG5hLnJtID0gVCkpCgojSGlzdCBzaG93aW5nIGRpc3RyaWIuIG9mIFJUcyAoc2hvdWxkIHdlIGxvZyB0cmFuc2Zvcm0/KQpoaXN0KGQkYWJzVmFsKQoKI0NvbnZlcnQgc3ViamVjdCB0byBhIGZhY3RvciBhbmQgdmFsQmluIHRvIG51bWVyaWMKc3ViamVjdF9tZWFucyRzdWJqZWN0ID0gYXMuZmFjdG9yKHN1YmplY3RfbWVhbnMkc3ViamVjdCkKc3ViamVjdF9tZWFucyR2YWxCaW4gPSBhcy5udW1lcmljKHN1YmplY3RfbWVhbnMkdmFsQmluKQpkZiRzdWJqZWN0ID0gYXMuZmFjdG9yKGRmJHN1YmplY3QpCgojTmVlZCBzZXF1ZW50aWFsbHkgb3JkZXJlZCBzdWJqZWN0cwpzdWJqZWN0X21lYW5zJHN1YmplY3RPcmRlcmVkID0gMAp4PTEKZm9yKGkgaW4gMToyNCl7CiAgZm9yKGogaW4gMTo3KXsKICAgIHN1YmplY3RfbWVhbnMkc3ViamVjdE9yZGVyZWRbeF0gPSBpCiAgICB4PXgrMQogIH0KfQoKZGYkc3ViamVjdE9yZGVyZWQgPSAwCmZvcihpIGluIDE6MjQpewogIGRmJHN1YmplY3RPcmRlcmVkW2ldID0gaQp9CgojcnRfcHJlZGljdGVkID0gc3ViamVjdCBpbnRlcmNlcHQgKyBzbG9wZSpNSURETEUgb2YgQmluIFZhbHVlCiNJTlRFUkNFUFQKc3ViamVjdF9tZWFucyRpbnRlcmNlcHQgPSAwCmZvcihpIGluIDE6MjQpewogIHN1YmplY3RfbWVhbnMkaW50ZXJjZXB0W3N1YmplY3RfbWVhbnMkc3ViamVjdE9yZGVyZWQ9PWldID0gZGYkaW50ZXJjZXB0W2RmJHN1YmplY3RPcmRlcmVkPT1pXSAKfQojUlRfUFJFRElDVCAodXNpbmcgc2xvcGUpCnN1YmplY3RfbWVhbnMkcnRfcHJlZGljdCA9IDAKZm9yKGkgaW4gMToyNCl7CiAgZm9yKGogaW4gMTo3KXsKICAgIHN1YmplY3RfbWVhbnMkcnRfcHJlZGljdFtzdWJqZWN0X21lYW5zJHN1YmplY3RPcmRlcmVkPT1pJnN1YmplY3RfbWVhbnMkdmFsQmluPT1qXSA9CiAgICAgIGRmJGFic1ZhbFtkZiRzdWJqZWN0T3JkZXJlZD09aV0gKiAoaiowLjUtMC4yNSkgKyBzdWJqZWN0X21lYW5zJGludGVyY2VwdFtpKjddIAogICAgI3N1YnRyYWN0aW5nIDAuMjUgdG8gZ2V0IHZhbHVlIGluIG1pZGRsZSBvZiBiaW4uLi5hcyB0aGUgYmlubmVkIHZhbHVlIGlzIHRoZSBhdmVyYWdlIG9mIGFsbCB2YWx1ZXMgd2l0aGluIHRoZSBiaW4gcmFuZ2UKICB9Cn0KCiNwbG90IHdpdGggYWN0dWFsIGRhdGEKZ2dwbG90KHN1YmplY3RfbWVhbnMsYWVzKHg9dmFsQmluLHk9cnRfcHJlZGljdCxjb2xvcj1zdWJqZWN0KSkrCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludChkYXRhPXN1YmplY3RfbWVhbnMsYWVzKHg9KHZhbEJpbikseT1ydCkpKwogIGZhY2V0X3dyYXAofnN1YmplY3QsbnJvdz02KQpgYGAKCiMjIEFQQSBGb3JtYXQgUGxvdHRpbmcKYGBge3J9CmFwYXRoZW1lPXRoZW1lX2J3KCkrCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvcj1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vcj1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9saW5lKCksCiAgICAgICAgdGV4dD1lbGVtZW50X3RleHQoZmFtaWx5PSdUaW1lcycpKQpgYGAKCiMjTE1FCiMjI3dpdGggaGVscCBmcm9tIExpegoKYGBge3IgbG1lLWxpejAxLCBlY2hvPVRSVUV9CmxpYnJhcnkobG1lNCkKbGlicmFyeShubG1lKQpsaWJyYXJ5KHNqUGxvdCkKZCA8LSBTX00KYW0yIDwtIGxtZShsb2dSVCB+IG11bHROdW0rYWJzU3VtbWVkVmFsLCByYW5kb20gPSB+MSttdWx0TnVtfHN1YmplY3QsIGRhdGE9ZCkKc3VtbWFyeShhbTIpCgojQXNzdW1pbmcgdGhlIGZvcm1lciwgdGhvdWdoIChpLmUuLCB5b3UgbWVhbnQgbXVsdE51bSB0byBiZSBhIHJhbmRvbSBzbG9wZSksIHRoZW4geW91IHdvdWxkIGFkZGl0aW9uYWxseSBhZGQgYSByYW5kb20gc2xvcGUgZm9yIGFic1ZhbDoKCmQkbXVsdE51bUYgPC0gZmFjdG9yKGQkbXVsdE51bSkKY3RybCA8LSBsbWVDb250cm9sKG9wdD0nb3B0aW0nKTsKYW0yIDwtIGxtZShsb2dSVCB+IG11bHROdW1GK2Fic1N1bW1lZFZhbCwgcmFuZG9tID0gfjErbXVsdE51bUYrYWJzU3VtbWVkVmFsfHN1YmplY3QsIGNvbnRyb2w9Y3RybCwgZGF0YT1kKQpzdW1tYXJ5KGFtMikKCgojIyNGUk9NIEJFRk9SRSMjCmFtMiA8LSBsbWUobG9nUlQgfiBtdWx0TnVtRiwgcmFuZG9tID0gfjF8c3ViamVjdC9tdWx0TnVtRiwgZGF0YT10b3RhbF9NX2NsZWFuMykKc3VtbWFyeShhbTIpCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwojIE5FVyBNSVhFRCBFRkZFQ1RTIE1PREVMSU5HIEJBU0VEIE9OIFJFU1VMVFMgU0VDVElPTiAgIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jCiMgMS4gU1RVRFkgQ09NUEFSSVNPTiAgIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMKIyBBcmUgdGhlaXIgcGVyZm9yYW1uY2UgZGlmZmVyZW5jZXMgdGhhdCBhcmUgY2F1c2VkIGJ5IHRoZSBkaWZmZXJlbmNlIGluIHN0dWR5IHBhcmFkaWdtPwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jCiMgTWFuaXB1bGF0ZSBEYXRhICAgICAgIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMKCiMgQ29tYmluZSB0aGUgU3dhcCBhbmQgTm9uLVN3YXAgRXhwZXJpbWVudHMgYW5kIGxhYmVsIHRoZW0gYnkgU3R1ZHkKbG9hZCgiRGF0YS9OU19NLlJkYXRhIikKCmQxIDwtIE5TX00KZDIgPC0gU19NCgojIENyZWF0ZSBJRCBmb3IgZWFjaCBERgpkMSRzdHVkeSA8LSAiU3RhbmRhcmQgTXVsdC4iCmQyJHN0dWR5IDwtICJTd2FwIE11bHQuIgoKIyBOZWVkIHRvIHVuaXF1ZWx5IG51bWJlciBTdWJqZWN0cwpkMiRzdWJqZWN0IDwtIGQyJHN1YmplY3QgKyAxMDAKCiMgQ29uY2F0IERGcwpjb21tb25fY29scyA8LSBpbnRlcnNlY3QoY29sbmFtZXMoZDEpLCBjb2xuYW1lcyhkMikpCmRmID0gcmJpbmQoCiAgZDFbLCBjb21tb25fY29sc10sIAogIGQyWywgY29tbW9uX2NvbHNdCikKCiMgU3R1ZHkgYW5kIHN1YmplY3RzIGFzIGZhY3RvcgpkZiRzdHVkeSA8LSBmYWN0b3IoZGYkc3R1ZHkpCmRmJHN1YmplY3QgPC0gZmFjdG9yKGRmJHN1YmplY3QpCgojIENyZWF0ZSBsb2dSVCBjb2x1bW4KZGYkbG9nUlQgPSBsb2coZGYkcnQpCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMKIyBNaXhlZCBFZmZlY3RzIE1vZGVscyAjCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwoKIyBudWxsIG1vZGVsLCBncm91cGluZyBieSBzY2hvb2wgYnV0IG5vdCBmaXhlZCBlZmZlY3RzLgpudWxsIDwtZ2xtZXIoY29ycmVjdCB+IDEgKyAoMXxzdWJqZWN0KSwgZmFtaWx5ID0gYmlub21pYWwoImxvZ2l0IiksIGRhdGE9ZGYpCnN1bW1hcnkobnVsbCkKCiMgTW9kZWwgd2l0aCBmaXhlZCBlZmZlY3RzCmZpdCA8LSBnbG1lcihjb3JyZWN0IH4gc3VtbWVkVmFsKnN0dWR5ICsgYWJzKHN1bW1lZFZhbCkqc3R1ZHkgKyAoMSArIHN1bW1lZFZhbCArIGFicyhzdW1tZWRWYWwpfHN1YmplY3QpLCBmYW1pbHkgPSBiaW5vbWlhbCgibG9naXQiKSwgZGF0YSA9IGRmKQpzdW1tYXJ5KGZpdCkKCiMgbnVsbCBtb2RlbCwgZ3JvdXBpbmcgYnkgc2Nob29sIGJ1dCBub3QgZml4ZWQgZWZmZWN0cy4KbnVsbCA8LWxtZXIobG9nUlQgfiAxICsgKDF8c3R1ZHkpICsgKDF8c3ViamVjdCksIGRhdGE9ZGYsIFJFTUwgPSBGQUxTRSkKc3VtbWFyeShudWxsKQoKIyBNb2RlbCB3aXRoIGZpeGVkIGVmZmVjdHMKZml0IDwtIGxtZXIobG9nUlQgfiBzdW1tZWRWYWwqc3R1ZHkgKyBhYnMoc3VtbWVkVmFsKSpzdHVkeSArICgxICsgc3VtbWVkVmFsICsgYWJzKHN1bW1lZFZhbCl8c3ViamVjdCksIGRhdGEgPSBkZiwgUkVNTCA9IEZBTFNFKQpzdW1tYXJ5KGZpdCkKbGlicmFyeShjYXIpICAjIG5vdGUgdGhlIGNyaXRpcXVlIG9mIHVzaW5nIHRoaXMgKGh0dHA6Ly9iYm9sa2VyLmdpdGh1Yi5pby9taXhlZG1vZGVscy1taXNjL2dsbW1GQVEuaHRtbCN3aGF0LWFyZS10aGUtcC12YWx1ZXMtbGlzdGVkLWJ5LXN1bW1hcnlnbG1lcmZpdC1ldGMuLWFyZS10aGV5LXJlbGlhYmxlKQpBbm92YShmaXQpCgojIElzIGNob2ljZSBhZmZlY3RlZCBieSBOZXQgVmFsdWU/CmZpdCA8LSBnbG1lcihjaG9pY2UgfiBzdW1tZWRWYWwgKyAoMSArIHN1bW1lZFZhbCB8IHN1YmplY3QpLCBmYW1pbHkgPSBiaW5vbWlhbCgibG9naXQiKSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQoKIyBJcyBhY2N1cmFjeSBhZmZlY3RlZCBieSBuZXQvYWJzIHZhbHVlPwpmaXQgPC0gZ2xtZXIoY29ycmVjdCB+IHN1bW1lZFZhbCArIGFicyhzdW1tZWRWYWwpICsgKDEgKyBzdW1tZWRWYWwgKyBhYnMoc3VtbWVkVmFsKSB8IHN1YmplY3QpLCBmYW1pbHkgPSBiaW5vbWlhbCgibG9naXQiKSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQoKIyBJcyBjaG9pY2UgYWZmZWN0ZWQgYnkgaW50ZXJhY3Rpb24gTmV0IFZhbHVlIHggTXVsdD8KZml0IDwtIGdsbWVyKGNob2ljZSB+IHN1bW1lZFZhbCAqIGZhY3RvcihtdWx0TnVtKSArICgxICsgc3VtbWVkVmFsICogZmFjdG9yKG11bHROdW0pIHwgc3ViamVjdCksIGZhbWlseSA9IGJpbm9taWFsKCJsb2dpdCIpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQpCgojIElzIGNob2ljZSBhZmZlY3RlZCBieSBpbnRlcmFjdGlvbiBiZXR3ZWVuIGluZGl2aWR1YWwgYXR0cmlidXRlcyBhbmQgdGhlaXIgaW5kaXZpZHVhbCBtdWx0cz8KZml0IDwtIGdsbWVyKGNob2ljZSB+IGZhY2VWYWwgKiBtdWx0MkZhY2UgKyBob3VzZVZhbCAqIG11bHQxSG91c2UgKyAoMSArIGZhY2VWYWwgKiBtdWx0MkZhY2UgKyBob3VzZVZhbCAqIG11bHQxSG91c2UgfCBzdWJqZWN0KSwgZmFtaWx5ID0gYmlub21pYWwoImxvZ2l0IiksIGRhdGEgPSBkKQpzdW1tYXJ5KGZpdCkKCiMgSXMgYWNjdXJhY3kgYWZmZWN0IGJ5IGludGVyYWN0aW9uIGJldHdlZW4gYWJzL3N1bW1lZCB2YWwgYW5kIG11bHRzPwpmaXQgPC0gZ2xtZXIoY29ycmVjdCB+IHN1bW1lZFZhbCAqIGZhY3RvcihtdWx0TnVtKSArIGFicyhzdW1tZWRWYWwpICogZmFjdG9yKG11bHROdW0pICsgKDEgKyBzdW1tZWRWYWwgKiBmYWN0b3IobXVsdE51bSkgKyBhYnMoc3VtbWVkVmFsKSAqIGZhY3RvcihtdWx0TnVtKSB8IHN1YmplY3QpLCBmYW1pbHkgPSBiaW5vbWlhbCgibG9naXQiKSwgY29udHJvbCA9IGdsbWVyQ29udHJvbChvcHRpbWl6ZXIgPSAiYm9ieXFhIiksIG5BR1EgPSAxMCwgZGF0YSA9ZCkKCmZpdCA8LSBnbG1lcihjb3JyZWN0IH4gc3VtbWVkVmFsICogZmFjdG9yKG11bHROdW0pICsgYWJzKHN1bW1lZFZhbCkgKiBmYWN0b3IobXVsdE51bSkgKyAoMSArIHN1bW1lZFZhbCAqIGZhY3RvcihtdWx0TnVtKSArIGFicyhzdW1tZWRWYWwpICogZmFjdG9yKG11bHROdW0pIHwgc3ViamVjdCksIGZhbWlseSA9IGJpbm9taWFsKCJsb2dpdCIpLCBkYXRhID1kKQpzdW1tYXJ5KGZpdCkKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLSMKIyBSZWFjdGlvbiBUaW1lICAgICAgIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0jCgpkIDwtIFNfTQoKIyBTdWJqZWN0IGFzIGZhY3RvcgpkJHN1YmplY3QgPC0gZmFjdG9yKGQkc3ViamVjdCkKCiMgQ3JlYXRlIGxvZ1JUIGNvbHVtbgpkJGxvZ1JUID0gbG9nKGQkcnQpCgojIFJ0IGFmZmVjcmVkIGJ5IE5ldCBWYWwgdnMuIEFicyhOZXQgVmFsKQpmaXQgPC0gbG1lcihsb2dSVCB+IHN1bW1lZFZhbCArIGFicyhzdW1tZWRWYWwpICsgKDEgKyBzdW1tZWRWYWwgKyBhYnMoc3VtbWVkVmFsKSB8IHN1YmplY3QpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQpCkFub3ZhKGZpdCkKCiMgUnQgYWZmZWNyZWQgYnkgbXVsdG51bSBhbmQgbmV0L2Fic05ldCB2YWxzCmZpdCA8LSBsbWVyKGxvZ1JUIH4gc3VtbWVkVmFsKmZhY3RvcihtdWx0TnVtKSArIGFicyhzdW1tZWRWYWwpICogZmFjdG9yKG11bHROdW0pICsgKDEgKyBzdW1tZWRWYWwqZmFjdG9yKG11bHROdW0pICsgYWJzKHN1bW1lZFZhbCkgKiBmYWN0b3IobXVsdE51bSkgfCBzdWJqZWN0KSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQpBbm92YShmaXQpCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwojIEF0dHJpYi4gRWZmZWN0cyBvbiBDaG9pY2UvUlQgIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIwoKIyBDaG9pY2UgYWZmZWN0ZWQgYnkgZmFjZS9ob3VzZT8KZml0IDwtIGdsbWVyKGNob2ljZSB+IGZhY2VWYWwgKiBtdWx0MkZhY2UgKyBob3VzZVZhbCAqIG11bHQxSG91c2UgKyAoMSArIGZhY2VWYWwgKiBtdWx0MkZhY2UgKyBob3VzZVZhbCAqIG11bHQxSG91c2UgfCBzdWJqZWN0KSwgZmFtaWx5ID0gYmlub21pYWwoImxvZ2l0IiksIGRhdGEgPSBkKQpzdW1tYXJ5KGZpdCkKCiMgU2ltcGxlciB2ZXJzaW9uCmZpdCA8LSBnbG1lcihjaG9pY2UgfiBmYWNlVG90YWwgKyBob3VzZVRvdGFsICsgKDEgKyBmYWNlVG90YWwgKyBob3VzZVRvdGFsIHwgc3ViamVjdCksIGZhbWlseSA9IGJpbm9taWFsKCJsb2dpdCIpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQpCgojIEFjY3VyYWN5IGFmZmVjdGVkIGJ5IGZhY2UvaG91c2UKZml0IDwtIGdsbWVyKGNvcnJlY3QgfiBhYnMoZmFjZVZhbCkqbXVsdDJGYWNlICsgYWJzKGhvdXNlVmFsKSptdWx0MUhvdXNlICsgKDEgKyBhYnMoZmFjZVZhbCkqbXVsdDJGYWNlICsgYWJzKGhvdXNlVmFsKSptdWx0MUhvdXNlIHwgc3ViamVjdCksIGZhbWlseSA9IGJpbm9taWFsKCJsb2dpdCIpLCBjb250cm9sPWdsbWVyQ29udHJvbChvcHRpbWl6ZXI9ImJvYnlxYSIsIG9wdEN0cmw9bGlzdChtYXhmdW49MmU1KSksIGRhdGEgPSBkKQpzdW1tYXJ5KGZpdCkKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLSMKIyBGaXhhdGlvbnMgICAgICAgICAgIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0jCgojIEZpeGF0aW9uIEJpYXMgcHJlZGljdGl2ZSBvZiBjaG9pY2UgZm9yIGhvdXNlIG9yIGZhY2U/CmQgPC0gU19NCmQkc3ViamVjdCA8LSBmYWN0b3IoZCRzdWJqZWN0KQoKIyBOdW1iZXIgb2Ygc3dhcHMgYWZmZWNlZCBieSBuZXQgdmFsdWUgKHllcykKZml0IDwtIGxtZXIoc3dhcEFtb3VudCB+IHN1bW1lZFZhbCArIGFicyhzdW1tZWRWYWwpICsgKDEgKyBzdW1tZWRWYWwgKyBhYnMoc3VtbWVkVmFsKSB8IHN1YmplY3QpLCBkYXRhID1kKQpzdW1tYXJ5KGZpdCkKQW5vdmEoZml0KQoKIyBDaG9pY2UgYWZmZWN0ZWQgYnkgZml4YXRpb24gdGltZSBvbiBob3VzZS9mYWNlIChubykKZml0IDwtIGdsbWVyKGNob2ljZSB+IHRvdGFsXzBfZmFjZSArIHRvdGFsXzFfaG91c2UgKyAoMSArIHRvdGFsXzBfZmFjZSArIHRvdGFsXzFfaG91c2V8c3ViamVjdCksIGZhbWlseSA9IGJpbm9taWFsKCJsb2dpdCIpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQpCgojIEZpeGF0aW9uIHRpbWUgb24gRmFjZSBhZmZlY3RlZCBieSB3aGF0PwpmaXQgPC0gbG1lcih0b3RhbF8wX2ZhY2UgfiBmYWNlVmFsKm11bHQyRmFjZSArIGhvdXNlVmFsKm11bHQxSG91c2UgKyAoMSArIGZhY2VWYWwqbXVsdDJGYWNlICsgaG91c2VWYWwqbXVsdDFIb3VzZSB8IHN1YmplY3QpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQpCkFub3ZhKGZpdCkKCiMgRml4YXRpb24gdGltZSBvbiBIb3VzZSBhZmZlY3RlZCBieSB3aGF0PwpmaXQgPC0gbG1lcih0b3RhbF8xX2hvdXNlIH4gZmFjZVZhbCptdWx0MkZhY2UgKyBob3VzZVZhbCptdWx0MUhvdXNlICsgKDEgKyBmYWNlVmFsKm11bHQyRmFjZSArIGhvdXNlVmFsKm11bHQxSG91c2UgfCBzdWJqZWN0KSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQpBbm92YShmaXQpCgojIEZpbmFsIEZpeGF0aW9uIHZhbHVlIHByZWRpY3RpdmUgb2YgY2hpb2NlPwojIExhc3QgaW1hZ2UgdmFsCmQkbGFzdFZhbCA8LSBkJGZhY2VUb3RhbApkJGxhc3RNdWx0IDwtIGQkbXVsdDJGYWNlCmZvcihpIGluIDE6bGVuZ3RoKGQkVHJpYWwpKXsKICBpZihkJGxhc3RJbWFnZVtpXSA9PSAxKXsKICAgIGQkbGFzdFZhbFtpXSA8LSBkJGhvdXNlVmFsW2ldCiAgICBkJGxhc3RNdWx0W2ldIDwtIGQkbXVsdDFIb3VzZVtpXQogIH0KfQoKbG9hZCgiRGF0YS9TX01fSy5SZGF0YSIpCmQ8LSBTX01fSwpkJHN1YmplY3QgPC0gZmFjdG9yKGQkc3ViamVjdCkgCiMgZGVsZXRlIGFsbCByb3dzIGJ1dCBmaW5hbCBmaXgKZCA8LSBkWyB3aGljaChkJHJldkZpeE51bT09MSksIF0gIyBvbmx5IGZpbmFsIGZpeGF0aW9ucwpmaXQgPC0gZ2xtZXIoY2hvaWNlIH4gZml4RHVyICsgKDEgKyBmaXhEdXJbcmV2Rml4TnVtID09MV18IHN1YmplY3QpLCBmYW1pbHkgPSBiaW5vbWlhbCgibG9naXQiKSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQoKZml0IDwtIGdsbWVyKGNob2ljZSB+IHJvaSArICgxICsgcm9pIHwgc3ViamVjdCksIGZhbWlseSA9IGJpbm9taWFsKCJsb2dpdCIpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQpCgojZmluYWwgZml4IGFmZmVjdGVkIGJ5IHRvdGFsIHZhbHVlIChtb3Jlc28gZm9yIGFic29sdXRlKQpmaXQgPC0gZ2xtZXIocm9pIH4gdG90VmFsRmFjZSArIHRvdFZhbEhvdXNlICsgKDEgKyB0b3RWYWxGYWNlICsgdG90VmFsSG91c2UgfCBzdWJqZWN0KSwgZmFtaWx5ID0gYmlub21pYWwoImxvZ2l0IiksIGRhdGEgPSBkKQpzdW1tYXJ5KGZpdCkKCiMgU2Vjb25kIGZpeGF0aW9uCiMgbWFrZSB0aGUgZGF0YQpkPC0gU19NX0sKZCRzdWJqZWN0IDwtIGZhY3RvcihkJHN1YmplY3QpIAojIGRlbGV0ZSBhbGwgcm93cyBidXQgc2VsZWN0ZWQKZCA8LSBkWyB3aGljaChkJGZpeE51bT09MiksIF0gIyBvbmx5IDJuZCBmaXhhdGlvbnMKZCA8LSBkWyB3aGljaChkJHJldkZpeE51bT09MSksIF0gIyBvbmx5IGZpbmFsIGZpeGF0aW9ucwoKIyBGaW5hbCBmaXggaXRlbSBqdXN0IGJhc2VkIG9uIHZhbHVlCmQkcm9pIDwtIGZhY3RvcihkJHJvaSkKZml0IDwtIGdsbWVyKHJvaSB+IGFicyh0b3RWYWxGYWNlKSArIGFicyh0b3RWYWxIb3VzZSkgKyAoYWJzKHRvdFZhbEZhY2UpICsgYWJzKHRvdFZhbEhvdXNlKSB8IHN1YmplY3QpLCBmYW1pbHkgPSBiaW5vbWlhbCgibG9naXQiKSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQoKIyBmaW5hbCBmaXggcm9pIGFzIHByZWRpY3RlZCBieSBhYnMoZmFjZXRvdGFsKSArIGFicyhob3VzZVRvdGFsKSArIGFicyhmYWNlVmFsKSpmYWNlTXVsdCArIGFicyhob3VzZVZhbCkqaG91c2VNdWx0CmQkcm9pIDwtIGZhY3RvcihkJHJvaSkKZml0IDwtIGdsbWVyKHJvaSB+IGFicyhmYWNlVmFsKSptdWx0RmFjZSArIGFicyhob3VzZVZhbCkqbXVsdEhvdXNlICsgKGFicyhmYWNlVmFsKSptdWx0RmFjZSArIGFicyhob3VzZVZhbCkqbXVsdEhvdXNlIHwgc3ViamVjdCksIGZhbWlseSA9IGJpbm9taWFsKCJsb2dpdCIpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQpCgojIFRhYmxlIGZvciBnbG1lcgpzanQuZ2xtZXIoZml0LCBkZXB2YXIubGFiZWxzID0gIkZpbmFsIEZpeGF0aW9uIEF0dHJpYnV0ZSAoRmFjZSAwLCBIb3VzZSAxKSIsIGV4cC5jb2VmID0gRkFMU0UsIAogICAgICAgICAgZGlnaXRzLmVzdCA9IDMsIHNob3cuY2kgPSBGQUxTRSwgc2hvdy5zZSA9IFRSVUUpCgojIGZpeCBhbmQgbm9uIGZpeCBpdGVtcwoKIyBVbndlaWdodGVkIFZhbApkJHZhbEZpeEl0ZW0gPC0gZCRmYWNlVmFsCmQkdmFsTm9uRml4SXRlbSA8LSBkJGhvdXNlVmFsCmZvcihpIGluIDE6bGVuZ3RoKGQkdHJpYWwpKXsKICBpZihkJHJvaVtpXSA9PSAxKXsKICAgIGQkdmFsRml4SXRlbVtpXSA8LSBkJGhvdXNlVmFsW2ldCiAgICBkJHZhbE5vbkZpeEl0ZW1baV0gPC0gZCRmYWNlVmFsW2ldCiAgfQp9CgojIFdlaWdodGVkIFZhbApkJHZhbEZpeEl0ZW0gPC0gZCR0b3RWYWxGYWNlCmQkdmFsTm9uRml4SXRlbSA8LSBkJHRvdFZhbEhvdXNlCmZvcihpIGluIDE6bGVuZ3RoKGQkdHJpYWwpKXsKICBpZihkJHJvaVtpXSA9PSAxKXsKICAgIGQkdmFsRml4SXRlbVtpXSA8LSBkJHRvdFZhbEhvdXNlW2ldCiAgICBkJHZhbE5vbkZpeEl0ZW1baV0gPC0gZCR0b3RWYWxGYWNlW2ldCiAgfQp9CgojbG9nKGZpeGF0aW9uIGR1cmF0aW9uKSB+IGFicyh2YWxGaXhJdGVtKSArIGFicyh2YWxOb25GaXhJdGVtKSArIHZhbEZpeEl0ZW0gKyB2YWxOb25GaXhJdGVtCiMgTG9vayBhdCB3ZWlnaHRpbmcgYW5kIHVud2VpZ2h0ZWQgdmFsdWVzCmZpdCA8LSBsbWVyKGxvZyhmaXhEdXIpIH4gYWJzKHZhbEZpeEl0ZW0pICsgYWJzKHZhbE5vbkZpeEl0ZW0pICsgdmFsRml4SXRlbSArIHZhbE5vbkZpeEl0ZW0gKyAoMSArIGFicyh2YWxGaXhJdGVtKSArIGFicyh2YWxOb25GaXhJdGVtKSArIHZhbEZpeEl0ZW0gKyB2YWxOb25GaXhJdGVtIHwgc3ViamVjdCksIGRhdGEgPSBkKQpzdW1tYXJ5KGZpdCkKQW5vdmEoZml0KQoKZml0MSA8LSBsbWVyKGxvZyhmaXhEdXIpIH4gYWJzKHZhbEZpeEl0ZW0pICsgYWJzKHZhbE5vbkZpeEl0ZW0pICsgdmFsRml4SXRlbSArIHZhbE5vbkZpeEl0ZW0gKyAoMSArIGFicyh2YWxGaXhJdGVtKSArIGFicyh2YWxOb25GaXhJdGVtKSArIHZhbEZpeEl0ZW0gKyB2YWxOb25GaXhJdGVtIHwgc3ViamVjdCksIGRhdGEgPSBkKQpzdW1tYXJ5KGZpdDEpCmxpYnJhcnkoY2FyKQpBbm92YShmaXQxKQoKc2pwLmdsbWVyKGZpdDEsIHR5cGUgPSAiZWZmIiwgc2hvdy5jaSA9IFRSVUUpCnNqcC5sbWVyKGZpdDEsIHR5cGUgPSAicmkucGMiKQpzanAubG1lcihmaXQxLAogICAgICAgICBmYWNldC5ncmlkID0gRkFMU0UsCiAgICAgICAgIHNvcnQuZXN0ID0gInNvcnQuYWxsIiwKICAgICAgICAgeS5vZmZzZXQgPSAuNCkKCnNqcC5sbWVyKGZpdDEsIHR5cGUgPSAicHJlZCIsIHZhcnMgPSAiYWJzKHZhbEZpeEl0ZW0pIikKc2pwLmxtZXIoZml0MSwgdHlwZSA9ICJycy5yaSIsIHNhbXBsZS5uID0gMTUpCnNqcC5sbWVyKGZpdDEsIHR5cGUgPSAiZmUuc2xvcGUiKQpzanAubG1lcihmaXQxLCB0eXBlID0gImZlLnN0ZCIsIHAua3IgPSBGKQoKCnN1bW1hcnkoZml0MSkKCiMgaHR0cHM6Ly9zdHJlbmdlamFja2Uud29yZHByZXNzLmNvbS8yMDE1LzA2LzA1L2JlYXV0aWZ1bC10YWJsZS1vdXRwdXRzLXN1bW1hcml6aW5nLW1peGVkLWVmZmVjdHMtbW9kZWxzLXJzdGF0cy8KLkRlcHJlY2F0ZWQocF92YWx1ZSwgcGFja2FnZSA9ICJzalBsb3QiLCAnZ2V0X21vZGVsX3B2YWwnKQojIENyZWF0ZSBQbG90CnNqdC5sbWVyKGZpdCwgZml0MSwgcC5rciA9IEZBTFNFLCBzaG93LmNpID0gRkFMU0UsIHNob3cuc3RkID0gVFJVRSwKICAgICAgICAgZGVwdmFyLmxhYmVscyA9IGMoIkJhc2UgVmFsdWUiLCAiV2VpZ2h0ZWQgVmFsdWUiKSwgc2hvdy5oZWFkZXIgPSBUUlVFLAogICAgICAgICBkaWdpdHMuZXN0ID0gMywKICAgICAgICAgZmlsZSA9ICJsbWVyXzAxIikKCiMgUGxvdCByYW5kb20gRWZmZWN0cwpzanAubG1lcihmaXQsIGZhY2V0LmdyaWQgPSBGQUxTRSwKICAgICAgICAgc29ydC5lc3QgPSAic29ydC5hbGwiLAogICAgICAgICB5Lm9mZnNldCA9IC40KQoKIyBJZiBmaW5hbCBmaXggaXMgaG91c2UsIHdoYXQgYWJvdXQgdmFsdWVzCmQkcm9pIDwtIGZhY3RvcihkJHJvaSkKZml0IDwtIGdsbWVyKHJvaSB+IGZhY2VWYWwqbXVsdEZhY2UgKyBob3VzZVZhbCptdWx0SG91c2UgKyAoZmFjZVZhbCptdWx0RmFjZSArIGhvdXNlVmFsKm11bHRIb3VzZSB8IHN1YmplY3QpLCBmYW1pbHkgPSBiaW5vbWlhbCgibG9naXQiKSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQoKIyBEaWZmZXJlbmNlIGluIHZhbHVlIGJldHdlZW4gZmluYWwgZml4IGl0ZW0gYW5kIG5vbi1vYnNlcnZlZCBpdGVtCiMgZGlmIGNvbHVtbgpkJGRpZiA8LSAwCmQkZGlmW2QkZmluYWxGaXggPT0gMF0gPC0gYWJzKGQkdG90VmFsRmFjZSkgLSBhYnMoZCR0b3RWYWxIb3VzZSkKZCRkaWZbZCRmaW5hbEZpeCA9PSAxXSA8LSBhYnMoZCR0b3RWYWxIb3VzZSkgLSBhYnMoZCR0b3RWYWxGYWNlKQpmaXQgPC0gZ2xtZXIoZmluYWxGaXggfiBkaWYgKyAoMSArIGRpZiB8IHN1YmplY3QpLCBmYW1pbHkgPSBiaW5vbWlhbCgibG9naXQiKSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQoKZml0IDwtIGdsbWVyKGZpbmFsRml4IH4gdG90VmFsRmFjZSAqIHRvdFZhbEhvdXNlICsgKDEgKyB0b3RWYWxGYWNlICogdG90VmFsSG91c2UgfCBzdWJqZWN0KSwgZmFtaWx5ID0gYmlub21pYWwoImxvZ2l0IiksIGRhdGEgPSBkKQpzdW1tYXJ5KGZpdCkKCiMgUmVsb2FkIERhdGEKZCA8LSBTX00KZCRzdWJqZWN0IDwtIGZhY3RvcihkJHN1YmplY3QpCgojIEJpYXMgdG8gd2VpZ2ggdGhlIGZhY2UgdmFsdWUgbW9yZSB0aGFuIGp1c3RpZmllZD8KZml0IDwtIGdsbWVyKGNob2ljZSB+IGZhY2VUb3RhbCAqIHRvdGFsXzBfZmFjZSArIGhvdXNlVG90YWwgKiB0b3RhbF8xX2hvdXNlICsgKDEgKyBmYWNlVG90YWwgKiB0b3RhbF8wX2ZhY2UgKyBob3VzZVRvdGFsICogdG90YWxfMV9ob3VzZSB8IHN1YmplY3QpLCBmYW1pbHkgPSBiaW5vbWlhbCgibG9naXQiKSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQojIHR1cm4gaW50byBkYXRhZnJhbWUKZml0RGYgPC0gYXMuZGF0YS5mcmFtZS5tYXRyaXgoY29lZihzdW1tYXJ5KGZpdCkpKSAKbmFtZXMoZml0RGYpW25hbWVzKGZpdERmKSA9PSAiU3RkLiBFcnJvciJdIDwtICdzZScKbmFtZXMoZml0RGYpW25hbWVzKGZpdERmKSA9PSAieiB2YWx1ZSJdIDwtICd6JwpuYW1lcyhmaXREZilbbmFtZXMoZml0RGYpID09ICJQcig+fHp8KSJdIDwtICdwJwpmaXREZiQnRml4ZWQgRWZmZWN0cyc8LXJvd25hbWVzKGZpdERmKQoKIyByZW1vdmUgaW50ZXJjZXB0CmZpdERmID0gZml0RGZbLTEsXQpmaXREZlsxLDVdID0gIldGViIKZml0RGZbMiw1XSA9ICJURkQiCmZpdERmWzMsNV0gPSAiV0hWIgpmaXREZls0LDVdID0gIlRIRCIKZml0RGZbNSw1XSA9ICJXRlY6VEZEIgpmaXREZls2LDVdID0gIldIVjpUSEQiCgojIConcyBmb3Igc2lnbmlmaWNhbmNlCmZpdERmJHN0YXIgPC0gIiIKZml0RGYkc3RhcltmaXREZiRwIDw9IC4wNV0gIDwtICIqIgpmaXREZiRzdGFyW2ZpdERmJHAgPD0gLjAxXSAgPC0gIioqIgpmaXREZiRzdGFyW2ZpdERmJHAgPD0gLjAwMV0gPC0gIioqKiIKCiMgQmFyIFBsb3QKcG9zaXRpb25zIDwtIGMoIldGViIsICJXSFYiLCAiVEZEIiwgIlRIRCIsICJXRlY6VEZEIiwgIldIVjpUSEQiKQoKZ2dwbG90KGZpdERmLCBhZXMoYEZpeGVkIEVmZmVjdHNgLCB6LCBmaWxsPWBGaXhlZCBFZmZlY3RzYCkpICsgCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC41KSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49ei1zZSwgeW1heD16K3NlKSwgd2lkdGg9MC40KSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1zdGFyKSwgY29sb3VyPSJibGFjayIsIHZqdXN0PTAsIHNpemU9NikgKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gcG9zaXRpb25zKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KHNpemU9MTQpLAogICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCnNldHdkKCIvVXNlcnMvZGp3L0Ryb3Bib3gvUEhEL1BSRVNFTlRBVElPTlMvMjAxN19TTkUvUGxvdHMvIikKZ2dzYXZlKCJmaXhlZEVmZmVjdHMucGRmIiwgd2lkdGggPSAyMCwgaGVpZ2h0ID0gMTIsIHVuaXRzID0gImNtIikKCiMgcGxvdCBTSgpsaWJyYXJ5KHNqUGxvdCkKbGlicmFyeShzam1pc2MpCgpzanAuZ2xtZXIoZml0MSwgdHlwZSA9ICJmZS5zdGQiLCBwLmtyID0gRikKCiMgcGVyZWNwdCBhbWIuCiMgZml0IDQgPSBtdWx0TnVtIGFzIGNvbnRpbnVvdXMKIyBmaXQgNSA9IG11bHROdW0gYXMgZmFjdG9yCmZpdDUgPC0gZ2xtZXIoY29ycmVjdCB+IGZhY2VWYWwgKyBob3VzZVZhbCArIGFicyhmYWNlVmFsKSArIGFicyhob3VzZVZhbCkgKyBmYWN0b3IobXVsdE51bSkgKyBtdWx0RGlmICsgdG90YWxfMF9mYWNlICsgdG90YWxfMV9ob3VzZSArIHRvdGFsXzBfZmFjZTpmYWNlVmFsICsgdG90YWxfMF9mYWNlOmFicyhmYWNlVmFsKSArIHRvdGFsXzFfaG91c2U6aG91c2VWYWwgKyB0b3RhbF8xX2hvdXNlOmFicyhob3VzZVZhbCkgKyAoZmFjZVZhbCArIGhvdXNlVmFsICsgYWJzKGZhY2VWYWwpICsgYWJzKGhvdXNlVmFsKSArIGZhY3RvcihtdWx0TnVtKSArIG11bHREaWYgKyB0b3RhbF8wX2ZhY2UgKyB0b3RhbF8xX2hvdXNlICsgdG90YWxfMF9mYWNlOmZhY2VWYWwgKyB0b3RhbF8wX2ZhY2U6YWJzKGZhY2VWYWwpICsgdG90YWxfMV9ob3VzZTpob3VzZVZhbCArIHRvdGFsXzFfaG91c2U6YWJzKGhvdXNlVmFsKSB8IHN1YmplY3QpLCBmYW1pbHkgPSBiaW5vbWlhbCgibG9naXQiKSwgZGF0YSA9IGQpIApzdW1tYXJ5KGZpdDUpCgojIGZpdCA2CmZpdDYgPC0gZ2xtZXIoY29ycmVjdCB+IGFicyhmYWNlVmFsKSptdWx0MkZhY2UgKyBhYnMoaG91c2VWYWwpKm11bHQxSG91c2UgKyAoIGFicyhmYWNlVmFsKSptdWx0MkZhY2UgKyBhYnMoaG91c2VWYWwpKm11bHQxSG91c2UgfCBzdWJqZWN0KSwgZmFtaWx5ID0gYmlub21pYWwoImxvZ2l0IiksIGRhdGEgPSBkKSAKc3VtbWFyeShmaXQ2KQoKIyBmaXQgNwpmaXQ3IDwtIGdsbWVyKGNvcnJlY3QgfiBhYnMoZmFjZVZhbCkqbXVsdDJGYWNlKnRvdGFsXzBfZmFjZSArIGFicyhob3VzZVZhbCkqbXVsdDFIb3VzZSp0b3RhbF8xX2hvdXNlICsgKGFicyhmYWNlVmFsKSptdWx0MkZhY2UgKyBhYnMoaG91c2VWYWwpKm11bHQxSG91c2UgfCBzdWJqZWN0KSwgZmFtaWx5ID0gYmlub21pYWwoImxvZ2l0IiksIGRhdGEgPSBkKQpzdW1tYXJ5KGZpdDcpCgojIGZpdCA4CmZpdDggPC0gZ2xtZXIoY29ycmVjdCB+IGFicyhob3VzZVRvdGFsKSp0b3RhbF8xX2hvdXNlICsgYWJzKGZhY2VUb3RhbCkqdG90YWxfMF9mYWNlICsgKGFicyhob3VzZVRvdGFsKSp0b3RhbF8xX2hvdXNlICsgYWJzKGZhY2VUb3RhbCkqdG90YWxfMF9mYWNlIHwgc3ViamVjdCksIGZhbWlseSA9IGJpbm9taWFsKCJsb2dpdCIpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQ4KQoKIyBGaW5hbCBmaXgKZCRjaG9pY2UgPCBmYWN0b3IoZCRjaG9pY2UpCmZpdDIgPC0gZ2xtZXIoY2hvaWNlIH4gZmFjZVZhbCptdWx0RmFjZSArIGhvdXNlVmFsKm11bHRIb3VzZSArIChmYWNlVmFsKm11bHRGYWNlICsgaG91c2VWYWwqbXVsdEhvdXNlIHwgc3ViamVjdCksIGZhbWlseSA9IGJpbm9taWFsKCJsb2dpdCIpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQyKQoKIyBTcGVuZCBhIGJpdCBtb3JlIHRpbWUgbG9va2luZyBhdCBob3VzZXMuLi5wZXJjZXB0dWFsbHkgaGFyZGVyPwptZWFuKGQkdG90YWxfMF9mYWNlKQptZWFuKGQkdG90YWxfMV9ob3VzZSkKCiMgTGFzdCBGaXhhdGlvbiBWYWx1ZSBQcmVkaWN0aXZlIG9mIENob2ljZT8KZml0IDwtIGdsbWVyKGNob2ljZSB+IHRvdGFsXzBfZmFjZSArIHRvdGFsXzFfaG91c2UgKyAoMSArIHRvdGFsXzBfZmFjZSArIHRvdGFsXzFfaG91c2V8c3ViamVjdCksIGZhbWlseSA9IGJpbm9taWFsKCJsb2dpdCIpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQpCgojIExvZyBydCBhcyBkZXRlcm1pbmVkIGJ5IGZpcnN0IGZpeCBuZXQgdmFsIGFuZCBtdWx0CmxvYWQoIkRhdGEvU19NLlJkYXRhIikKZCA8LSBTX00KZCRzdWJqZWN0IDwtIGZhY3RvcihkJHN1YmplY3QpCmQkZmlyc3RWYWxSYXcgPC0gZCRmaXJzdFZhbC9kJGZpcnN0TXVsdApkJGxvZ0ZpcnN0IDwtIGxvZyhkJGAxX2ZpeGF0aW9uYCkKZCRhYnNGaXJzdFZhbCA8LSBhYnMoZCRmaXJzdFZhbCkKZml0IDwtIGxtZXIobG9nRmlyc3QgfiAgZmlyc3RWYWxSYXcqZmlyc3RNdWx0ICsgYWJzRmlyc3RWYWwgKyAoMSsgZmlyc3RWYWxSYXcqZmlyc3RNdWx0ICsgYWJzRmlyc3RWYWwgfCBzdWJqZWN0KSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQpBbm92YShmaXQpCgojIDJuZCBGaXgKZCRzZWNvbmRWYWxSYXcgPC0gZCRzZWNvbmRWYWwvZCRzZWNvbmRNdWx0CmQkbG9nU2Vjb25kIDwtIGxvZyhkJGAyX2ZpeGF0aW9uYCkKZCRhYnNTZWNvbmRWYWwgPC0gYWJzKGQkc2Vjb25kVmFsKQpmaXQgPC0gbG1lcihsb2dTZWNvbmQgfiAgc2Vjb25kVmFsUmF3KnNlY29uZE11bHQgKyBhYnNTZWNvbmRWYWwgKyAoMSsgc2Vjb25kVmFsUmF3KnNlY29uZE11bHQgKyBhYnNTZWNvbmRWYWwgfCBzdWJqZWN0KSwgZGF0YSA9IGQpCnN1bW1hcnkoZml0KQpBbm92YShmaXQpIAoKZml0IDwtIGxtZXIobG9nU2Vjb25kIH4gIGFic1N1bW1lZFZhbCArIHN1bW1lZFZhbCArIG11bHROdW0gKyAoMSsgYWJzU3VtbWVkVmFsICsgc3VtbWVkVmFsICsgbXVsdE51bSB8IHN1YmplY3QpLCBkYXRhID0gZCkKc3VtbWFyeShmaXQpCkFub3ZhKGZpdCkgCgpsaWJyYXJ5KGVmZmVjdHMpCnBsb3QoYWxsRWZmZWN0cyhmaXQpKQoKCmBgYAoKIyNUZXN0IHRvIHNlZSBpZiBSVCBmb3IgaW5jb3JyZWN0IGlzIGxvbmdlciB0aGFuIFJUIGZvciBjb3JyZWN0PwoKYGBge3IgaW5jb3JyZWN0LWNvcnJlY3QsIGVjaG89RkFMU0V9CiNmaW5kIHN1YmplY3QgYWNjcnVhY3kgKHVuY2xlYW5lZCkKYWNjdXJhY3kgPSB0YXBwbHkodG90YWxfTV9jbGVhbjMkY29ycmVjdD09MSwgdG90YWxfTV9jbGVhbjMkc3ViamVjdCwgbWVhbikKCiNoaXN0cyBvZiBydCBiYXNlZCBvbiBjb25ncnVlbnQgYW5kIGluY29uZ3J1ZW50IHRyaWFscwpoaXN0KHRvdGFsX01fY2xlYW4zW3RvdGFsX01fY2xlYW4zJGNvcnJlY3Q9PTEsIF0kbG9nUlQsCiAgIGNvbD1yZ2IoMSwwLDAsMC41KSwgYnJlYWtzPXNlcSgtMS41LDIuNSwwLjA1KSwgeWxpbT1jKDAsMzAwKSwgeGxhYj0ibG9nIFJUIiwgbWFpbiA9ICJsb2cgUlQgdnMgRnJlcXVlbmN5IikKaGlzdCh0b3RhbF9NX2NsZWFuM1t0b3RhbF9NX2NsZWFuMyRjb3JyZWN0PT0wLCBdJGxvZ1JULAogICBjb2w9cmdiKDAsMCwxLDAuNSksIGJyZWFrcz1zZXEoLTEuNSwyLjUsMC4wNSksIHlsaW09YygwLDMwMCksIGFkZD1UKQpsZWdlbmQoInRvcHJpZ2h0IiwgYygiQ29ycmVjdCIsICJJbmNvcnJlY3QiKSwgZmlsbD1jKHJnYigxLDAsMCwwLjUpLCByZ2IoMCwwLDEsMC41KSkpCgojY3JlYXRlIHJ0cyBmb3IgZWFjaCBzdWJqZWN0IGJhc2VkIG9uIGNvbmdydWVudC9pbmNvbmdydWVudApydF9ieV9jb25kaXRpb24gPSB0YXBwbHkodG90YWxfTV9jbGVhbjMkbG9nUlQsIGxpc3QodG90YWxfTV9jbGVhbjMkc3ViamVjdCwgdG90YWxfTV9jbGVhbjMkY29ycmVjdCksIG1lYW4pCiNjb252ZXJ0IHRvIGRhdGEgZnJhbWUKcnRfYnlfY29uZGl0aW9uID0gYXMuZGF0YS5mcmFtZShydF9ieV9jb25kaXRpb24pIApuYW1lcyhydF9ieV9jb25kaXRpb24pID0gYygiaW5jb3JyZWN0IiwgImNvcnJlY3QiKQoKI2dldCBtZWFucwptZWFuX3J0cyA9IGFwcGx5KHJ0X2J5X2NvbmRpdGlvbiwgMiwgbWVhbikKI2dldCBTRQpuc3ViaiA9IGxlbmd0aChydF9ieV9jb25kaXRpb25bLDFdKQpzZHMgPSBhcHBseShydF9ieV9jb25kaXRpb24sIDIsIHNkKQpzZSA9IHNkcy9zcXJ0KG5zdWJqKQoKI0NSRUFURSBBIEJBUlBMT1QKeD1iYXJwbG90KG1lYW5fcnRzLCBjb2w9YyhyZ2IoMSwwLDAsMC41KSxyZ2IoMCwwLDEsMC41KSksbWFpbj0iUlQKICAgaW4gZWFjaCBjb25kaXRpb24iLHhsYWI9IkNvbmRpdGlvbiIseWxhYj0iUlQiLHlsaW0gPSBjKDAsMS4zKSkKc2VnbWVudHMoeCwgbWVhbl9ydHMtc2UsIHgsIG1lYW5fcnRzK3NlKQoKI1Rlc3QgZm9yIFNJRwp0b3RhbF9NX2NsZWFuMyRjb3JyZWN0ID0gYXMuZmFjdG9yKHRvdGFsX01fY2xlYW4zJGNvcnJlY3QpCnN1bW1hcnkobG1lKGxvZ1JUIH4gY29ycmVjdCwgcmFuZG9tID0gfjErY29ycmVjdHxzdWJqZWN0LCBkYXRhPXRvdGFsX01fY2xlYW4zKSkKYGBgCgoKI0xPT0tJTkcgQVQgUVVFU1RJT05OQUlSRSBEQVRBCiMjTm90ZSB0aGF0IHRoaXMgaXMgdGhlIGZvciB0aGUgImNsZWFuZWQiIHN1YmplY3RzLiBSdW5uaW5nIHRoaXMgd2l0aCBhbGwgb2YgdGhlIHN1YmplY3RzIGdpdmVzIGEgc2lnbmlmaWNhbnQgZWZmZWN0IHRvIFNlbGYtQ29udHJvbC4KCmBgYHtyIFF1ZXN0aW9ubmFpcmUtNS1mYWN0b3ItMDEsIGVjaG89RkFMU0V9CiNTZWxlY3QgZGF0YWZyYW1lIHRvIHVzZQpsb2FkKCJEYXRhL1NfTV9yYXcuUmRhdGEiKQpkMSA8LSBTX01fcmF3CmQyIDwtIHJlYWQuY3N2KCJEYXRhL05TX01fcmF3LmNzdiIpCmQyJG9yaWdOdW1iZXIgPC0gZDIkcGFydGljaXBhbnQKCiMgSk9JTiBEQVRBIEZSQU1FUwojIENyZWF0ZSBJRCBmb3IgZWFjaCBERgpkMSRzdHVkeSA8LSAiU3dhcCIKZDIkc3R1ZHkgPC0gIk5vU3dhcCIKCiMgUmVtb3ZlIHN1YmplY3QgY29scyAodXNpbmcgb3JpZ051bWJlcikKZDEkc3ViamVjdCA8LSBOVUxMCmQyJHN1YmplY3QgPC0gTlVMTAoKIyBDb25jYXQgREZzCmNvbW1vbl9jb2xzIDwtIGludGVyc2VjdChjb2xuYW1lcyhkMSksIGNvbG5hbWVzKGQyKSkKZCA9IHJiaW5kKAogIGQxWywgY29tbW9uX2NvbHNdLCAKICBkMlssIGNvbW1vbl9jb2xzXQopCgojIFJlbmFtZSBvcmlnTnVtYmVyIChqdXN0IHJlYWxpemVkIG5lZWRzIHRvIG1hdGNoIHN1cnZleSBkYXRhKQpuYW1lcyhkKVtuYW1lcyhkKT09Im9yaWdOdW1iZXIiXSA8LSAic3ViamVjdCIKCiNpbXBvcnQgUXVlc3Rpb25uYWlyZSBkYXRhCnNldHdkKCJ+L0Ryb3Bib3gvUEhEL0NFTkRSSS9Qcm9qZWN0L0NvZGUvTGFiU2hhcmVkRm9sZGVyL01BREUwMS9DT0RFL0dJVC9CZWhhdmlvcl9BbmFseXNpcyIpClF1ZXN0LmRmIDwtIHJlYWQuY3N2KCJjc3ZfZmlsZXMvUXVlc3Rpb25uYWlyZVJlc3VsdHMuY3N2IikKIyBuZWVkIHRvIHJlbmFtZSBwYXJ0aWNpcGFudCBJRApuYW1lcyhRdWVzdC5kZilbbmFtZXMoUXVlc3QuZGYpID09ICJQYXJ0aWNpcGFudC5JRCJdIDwtICJzdWJqZWN0IgojUXVlc3QuZGYgPC0gUXVlc3QuZGZbKFF1ZXN0LmRmJHN0dWR5X3ZlcnNpb24gPT0gMiksIF0KCiNtZWFuIFJUIGFuZCBGaW5hbCBlYXJuaW5ncyBieSBzdWJqZWN0CnN1YmplY3RfbWVhbnMgPC0gZ3JvdXBfYnkoZCwgc3ViamVjdCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShydCA9IG1lYW4ocnQsIG5hLnJtID0gVCksIGZpbmFsRWFybmluZ3MgPSBtZWFuKGZpbmFsRWFybmluZ3MsIG5hLnJtID0gVCksIGFjY3VyYWN5ID0gbWVhbihhcy5udW1lcmljKGNvcnJlY3QpKSkKCnN1YmplY3RfaW5mbyA8LSBncm91cF9ieShRdWVzdC5kZiwgc3ViamVjdCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShncGEgPSBtZWFuKEdQQSwgbmEucm0gPSBUKSwgZWZmb3J0ID0gbWVhbihFZmZvcnQsIG5hLnJtID0gVCksIGd1ZXNzID0gbWVhbihHdWVzc2luZywgbmEucm0gPSBUKSwgY29tcGFyYXRpdmUgPSBtZWFuKENvbXBhcmVkX3RvX290aGVycywgbmEucm0gPSBUKSkKCnN1YmplY3RfbWVhbnMgPC0gbWVyZ2Uoc3ViamVjdF9tZWFucywgUXVlc3QuZGYsIGJ5ID0gInN1YmplY3QiKQpzdWJqZWN0X21lYW5zCgojIEZvciBzZWxmIHJlcG9ydCBtZWFzdXJlcwpzdWJqZWN0X2luZm8gPC0gZ3JvdXBfYnkoUXVlc3QuZGYsIHN1YmplY3QpICU+JQogIGRwbHlyOjpzdW1tYXJpemUoZ3BhID0gbWVhbihHUEEsIG5hLnJtID0gVCksIGVmZm9ydCA9IG1lYW4oRWZmb3J0LCBuYS5ybSA9IFQpLCBndWVzcyA9IG1lYW4oR3Vlc3NpbmcsIG5hLnJtID0gVCksIGNvbXBhcmF0aXZlID0gbWVhbihDb21wYXJlZF90b19vdGhlcnMsIG5hLnJtID0gVCkpCgojbWVhbiBSVCBhbmQgQWNjdXJhY3kgYnkgc3ViamVjdApzdWJqZWN0X21lYW5zIDwtIGdyb3VwX2J5KGQsIHN1YmplY3QpICU+JQogIGRwbHlyOjpzdW1tYXJpemUocnQgPSBtZWFuKHJ0LCBuYS5ybSA9IFQpLCBhY2N1cmFjeSA9IG1lYW4oYXMubnVtZXJpYyhjb3JyZWN0KSwgbmEucm0gPSBUKSkKCnN1YmplY3RfbWVhbnMgPC0gbWVyZ2Uoc3ViamVjdF9tZWFucywgZGZfUXVlc3Rpb25uYWlyZSwgYnkgPSAic3ViamVjdCIpCgojIyMjIyMjIyMjIyMjIyMjIwojIEZVTkNUSU9OIFRPIFBVTEwgREFUQSBPVVQgT0YgTE0KIyMjIyMjIyMjIyMjIyMjIyMKCmdncGxvdFJlZ3Jlc3Npb24gPC0gZnVuY3Rpb24gKGZpdCkgewogIHJlcXVpcmUoZ2dwbG90MikKICBnZ3Bsb3QoZml0JG1vZGVsLCBhZXNfc3RyaW5nKHg9bmFtZXMoZml0JG1vZGVsKVsyXSwgeT1uYW1lcyhmaXQkbW9kZWwpWzFdKSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIHN0YXRfc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbCA9ICJyZWQiKSArCiAgICBnZ3RpdGxlKCJUZXN0aW5nIikgKwogICAgbGFicyh0aXRsZSA9IHBhc3RlKHRpdGxlLCAiXG5cbkFkaiBSMiA9ICIsc2lnbmlmKHN1bW1hcnkoZml0KSRhZGouci5zcXVhcmVkLCA1KSwKICAgICAgICAgICAgICAgICAgICAgICAiSW50ZXJjZXB0ID0iLHNpZ25pZihmaXQkY29lZltbMV1dLCA1KSwKICAgICAgICAgICAgICAgICAgICAgICAiU2xvcGUgPSIsc2lnbmlmKGZpdCRjb2VmW1syXV0sIDUpLAogICAgICAgICAgICAgICAgICAgICAgICJQID0iLHNpZ25pZihzdW1tYXJ5KGZpdCkkY29lZlsyLDRdLCA1KSkpCn0KCiMjIyMjIyMjIyMjIyMjIyMjCiMgRklWRSBGQUNUT1IgSU5ERVggT0YgUEVSU09OQUxJVFkKIyMjIyMjIyMjIyMjIyMjIyMKCiNFWFRSQVZFUlNJT04KI29sZCB2ZXJzaW9uCgojIGdncGxvdChzdWJqZWN0X21lYW5zLCBhZXMoeCA9IEV4dHJhdmVyc2lvbiwgeSA9IGFjY3VyYWN5KSkgKwojICAgZ2VvbV9wb2ludCgpICsKIyAgIHN0YXRfc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbCA9ICJyZWQiKQojIAojIHBsb3QoeCA9IHN1YmplY3RfbWVhbnMkRXh0cmF2ZXJzaW9uLCB5ID0gc3ViamVjdF9tZWFucyRhY2N1cmFjeSwKIyAgICAgIG1haW4gPSAiNSBGYWN0b3I6IFBlcmZvcm1hbmNlIGFzIHJlbGF0ZWQgdG8gRXh0cmF2ZXJzaW9uIiwKIyAgICAgIHlsYWIgPSAiQWNjdXJhY3kiLAojICAgICAgeGxhYiA9ICJFeHRyYXZlcnNpb24iKQojIGFibGluZShsbShzdWJqZWN0X21lYW5zJGFjY3VyYWN5fnN1YmplY3RfbWVhbnMkRXh0cmF2ZXJzaW9uKSwgY29sPSJyZWQiKSAjIHJlZ3Jlc3Npb24gbGluZSAoeX54KSAKIyAKIyAjdGVzdCBmb3Igc2lnbmlmaWNhbmNlCiMgc3VtbWFyeShsbShhY2N1cmFjeX5FeHRyYXZlcnNpb24sIHN1YmplY3RfbWVhbnMpKQoKI25ldyB2ZXJzaW9uCgp0aXRsZSA9ICI1IEZhY3RvcjogUGVyZm9ybWFuY2UgYXMgcmVsYXRlZCB0byBFeHRyYXZlcnNpb24iCmdncGxvdFJlZ3Jlc3Npb24obG0oYWNjdXJhY3l+RXh0cmF2ZXJzaW9uLCBkYXRhID0gc3ViamVjdF9tZWFucykpCgojTkVVUk9USUNJU00KdGl0bGUgPSAiNSBGYWN0b3I6IFBlcmZvcm1hbmNlIGFzIHJlbGF0ZWQgdG8gTmV1cm90aWNpc20iCmdncGxvdFJlZ3Jlc3Npb24obG0oYWNjdXJhY3l+TmV1cm90aWNpc20sIGRhdGEgPSBzdWJqZWN0X21lYW5zKSkKCiNDT05TQ0lFTlRJT1VTTkVTUwp0aXRsZSA9ICI1IEZhY3RvcjogUGVyZm9ybWFuY2UgYXMgcmVsYXRlZCB0byBDb25zY2llbnRpb3VzbmVzcyIKZ2dwbG90UmVncmVzc2lvbihsbShhY2N1cmFjeX5Db25zY2llbnRpb3VzbmVzcywgZGF0YSA9IHN1YmplY3RfbWVhbnMpKQoKI09QRU5ORVNTCnRpdGxlID0gIjUgRmFjdG9yOiBQZXJmb3JtYW5jZSBhcyByZWxhdGVkIHRvIE9wZW5uZXNzIgpnZ3Bsb3RSZWdyZXNzaW9uKGxtKGFjY3VyYWN5fk9wZW5uZXNzLCBkYXRhID0gc3ViamVjdF9tZWFucykpCgojQUdSRUVBQkxFTkVTUwp0aXRsZSA9ICI1IEZhY3RvcjogUGVyZm9ybWFuY2UgYXMgcmVsYXRlZCB0byBBZ3JlZWFibGVuZXNzIgpnZ3Bsb3RSZWdyZXNzaW9uKGxtKGFjY3VyYWN5fkFncmVlYWJsZW5lc3MsIGRhdGEgPSBzdWJqZWN0X21lYW5zKSkKCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgQkFSUkFUVCBJTVBVTFNJVklUWSBTQ0FMRQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgojQVRURU5USU9OCnRpdGxlID0gIkJJUzogUGVyZm9ybWFuY2UgYXMgcmVsYXRlZCB0byBBdHRlbnRpb24iCmdncGxvdFJlZ3Jlc3Npb24obG0oYWNjdXJhY3l+QXR0ZW50aW9uLCBkYXRhID0gc3ViamVjdF9tZWFucykpCgojQ09HTklUSVZFIElOU1RBQklMSVRZCnRpdGxlID0gIkJJUzogUGVyZm9ybWFuY2UgYXMgcmVsYXRlZCB0byBDb2duaXRpdmUgSW5zdGFiaWxpdHkiCmdncGxvdFJlZ3Jlc3Npb24obG0oYWNjdXJhY3l+Q29nbml0aXZlX0luc3RhYmlsaXR5LCBkYXRhID0gc3ViamVjdF9tZWFucykpCgojTU9UT1IKdGl0bGUgPSAiQklTOiBQZXJmb3JtYW5jZSBhcyByZWxhdGVkIHRvIE1vdG9yIgpnZ3Bsb3RSZWdyZXNzaW9uKGxtKGFjY3VyYWN5fk1vdG9yLCBkYXRhID0gc3ViamVjdF9tZWFucykpCgojUEVSU0VSVkVSQU5DRQp0aXRsZSA9ICJCSVM6IFBlcmZvcm1hbmNlIGFzIHJlbGF0ZWQgdG8gUGVyc2V2ZXJhbmNlIgpnZ3Bsb3RSZWdyZXNzaW9uKGxtKGFjY3VyYWN5flBlcnNldmVyYW5jZSwgZGF0YSA9IHN1YmplY3RfbWVhbnMpKQoKI1NFTEYgQ09OVFJPTAp0aXRsZSA9ICJCSVM6IFBlcmZvcm1hbmNlIGFzIHJlbGF0ZWQgdG8gU2VsZiBDb250cm9sIgpnZ3Bsb3RSZWdyZXNzaW9uKGxtKGFjY3VyYWN5flNlbGZfQ29udHJvbCwgZGF0YSA9IHN1YmplY3RfbWVhbnMpKQoKI0NPR05JVElWRSBDT01QTEVYSVRZCnRpdGxlID0gIkJJUzogUGVyZm9ybWFuY2UgYXMgcmVsYXRlZCB0byBDb2duaXRpdmUgQ29tcGxleGl0eSIKZ2dwbG90UmVncmVzc2lvbihsbShhY2N1cmFjeX5Db2duaXRpdmVfQ29tcGxleGl0eSwgZGF0YSA9IHN1YmplY3RfbWVhbnMpKQoKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBSQVRJT05BTC1FWFBFUklFTlRJQUwgSU5WRU5UT1JZCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCiNSQVRJT05BTCBBQklMSVRZCiNQRVJTRVJWRVJBTkNFCnRpdGxlID0gIlJJSTogUGVyZm9ybWFuY2UgYXMgcmVsYXRlZCB0byBSYXRpb25hbCBBYmlsaXR5IgpnZ3Bsb3RSZWdyZXNzaW9uKGxtKGFjY3VyYWN5flJhdGlvbmFsX0FiaWxpdHksIGRhdGEgPSBzdWJqZWN0X21lYW5zKSkKCiNSQVRJT05BTCBFTkdBR0VNRU5UCnRpdGxlID0gIlJJSTogUGVyZm9ybWFuY2UgYXMgcmVsYXRlZCB0byBSYXRpb25hbCBFbmdhZ2VtZW50IgpnZ3Bsb3RSZWdyZXNzaW9uKGxtKGFjY3VyYWN5flJhdGlvbmFsX0VuZ2FnZW1lbnQsIGRhdGEgPSBzdWJqZWN0X21lYW5zKSkKCiNFWFBFUklFTlRJQUwgQUJJTElUWQp0aXRsZSA9ICJSSUk6IFBlcmZvcm1hbmNlIGFzIHJlbGF0ZWQgdG8gRXhwZXJpZW50aWFsIEFiaWxpdHkiCmdncGxvdFJlZ3Jlc3Npb24obG0oYWNjdXJhY3l+RXhwZXJpZW50aWFsX0FiaWxpdHksIGRhdGEgPSBzdWJqZWN0X21lYW5zKSkKCiNFWFBFUklFTlRJQUwgRU5HQUdFTUVOVAp0aXRsZSA9ICJSSUk6IFBlcmZvcm1hbmNlIGFzIHJlbGF0ZWQgdG8gRXhwZXJpZW50aWFsIEVuZ2FnZW1lbnQiCmdncGxvdFJlZ3Jlc3Npb24obG0oYWNjdXJhY3l+RXhwZXJpZW50aWFsX0VuZ2FnZW1lbnQsIGRhdGEgPSBzdWJqZWN0X21lYW5zKSkKCmBgYAoKIyBNVUxUIERJRiBhbmQgTU9ERUxTLi4uCmBgYHtyIG11bHREaWYtMDEsIGVjaG89RkFMU0V9CiNDUkVBVEUgTkVXIENPTFVNTiBmb3IgbXVsdERpZgp0b3RhbF9NX2NsZWFuMyRtdWx0RGlmID0gYWJzKHRvdGFsX01fY2xlYW4zJG11bHQxSG91c2UgLSB0b3RhbF9NX2NsZWFuMyRtdWx0MkZhY2UpCnRvdGFsX01fY2xlYW4zJG11bHREaWZGID0gYXMuZmFjdG9yKHRvdGFsX01fY2xlYW4zJG11bHREaWYpCgojVEVTVCBNT0RFTApjdHJsIDwtIGxtZUNvbnRyb2wob3B0PSdvcHRpbScpOwoKI01PREVMIDFpOiBhYnNWYWwgKiBtdWx0TnVtICogbXVsdERpZiAoQklDIDg1OTAuOSkKbW9kZWwuMWkgPC0gbG1lKGxvZ1JUIH4gYWJzVmFsICogbXVsdE51bSAqIG11bHREaWYsIHJhbmRvbSA9IH4xK2Fic1ZhbCptdWx0TnVtfHN1YmplY3QsIGNvbnRyb2wgPSBjdHJsLCBkYXRhPXRvdGFsX01fY2xlYW4zKQpzdW1tYXJ5KG1vZGVsLjFpKQoKI01PREVMIDE6IGFic1ZhbCArIG11bHROdW0gKyBtdWx0RGlmICAgKEJJQyA4NjUxLjQpCm1vZGVsLjEgPC0gbG1lKGxvZ1JUIH4gYWJzVmFsK211bHROdW0rbXVsdERpZiwgcmFuZG9tID0gfjErbXVsdERpZittdWx0TnVtK2Fic1ZhbHxzdWJqZWN0LCBjb250cm9sPWN0cmwsIGRhdGE9dG90YWxfTV9jbGVhbjMpCnN1bW1hcnkobW9kZWwuMSkKCiNNT0RFTCAxZjogbXVsdE51bSAmIG11bHREaWYgYXMgRkFDVE9SUyAgIChCSUMgODczNC4zKQptb2RlbC4xZiA8LSBsbWUobG9nUlQgfiBhYnNWYWwrbXVsdE51bUYrbXVsdERpZkYsIHJhbmRvbSA9IH4xK211bHREaWZGK211bHROdW1GK2Fic1ZhbHxzdWJqZWN0LCBjb250cm9sPWN0cmwsIGRhdGE9dG90YWxfTV9jbGVhbjMpCnN1bW1hcnkobW9kZWwuMWYpCgoKI01PREVMIDI6IAojbW9kZWwuMiA8LSBsbWUobG9nUlQgfiBhYnNWYWwrbXVsdE51bSttdWx0RGlmK2ZhY2VWYWwraG91c2VWYWwrbXVsdDFIb3VzZSttdWx0MkZhY2UsIHJhbmRvbSA9IH4xK2Fic1ZhbCttdWx0TnVtK211bHREaWYrZmFjZVZhbCtob3VzZVZhbCttdWx0MUhvdXNlK211bHQyRmFjZXxzdWJqZWN0LCBjb250cm9sPWN0cmwsIGRhdGE9dG90YWxfTV9jbGVhbjMpCiNzdW1tYXJ5KG1vZGVsLjIpCgojTU9ERUwgMzoKI21vZGVsLjIgPC0gbG1lKGxvZ1JUIH4gYWJzVmFsK211bHROdW0rbXVsdERpZitmYWNlVmFsK2hvdXNlVmFsK211bHQxSG91c2UrbXVsdDJGYWNlLCByYW5kb20gPSB+MSthYnNWYWwrbXVsdE51bSttdWx0RGlmK2ZhY2VWYWwraG91c2VWYWwrbXVsdDFIb3VzZSttdWx0MkZhY2V8c3ViamVjdCwgY29udHJvbD1jdHJsLCBkYXRhPXRvdGFsX01fY2xlYW4zKQojc3VtbWFyeShtb2RlbC4yKQpgYGAKIyMjVEVTVCBUTyBTRUUgSUYgSU5URVJBQ1RJT04gSVMgU0lHTklGSUNBTlQKIyMjRi10ZXN0IGlzIHVzZWQgdG8gY29tcGFyZSB0aGUgcmVzaWR1YWwgc3VtIG9mIHNxdWFyZXMgb2YgYm90aCB0aGUgbW9kZWxzIApkcm9wMShtb2RlbC4xaSwgdGVzdCA9ICJGIikgICpkb2Vzbid0IHNlZW0gdG8gd29yayB3aXRoIGxtZSAoZXhhbXBsZSBpcyB3aXRoIGxtKQoKCiMjTU9ERUwgVkFMSURBVElPTgoKKGkpIHJlc2lkdWFscyB2ZXJzdXMgZml0dGVkIHZhbHVlcyB0byB2ZXJpZnkgaG9tb2dlbmVpdHkKCihpaSkgYSBRUS1wbG90IG9yIGhpc3RvZ3JhbSBvZiB0aGUgcmVzaWR1YWxzIGZvciBub3JtYWxpdHkKCihpaWkpIHJlc2lkdWFscyB2ZXJzdXMgZWFjaCBleHBsYW5hdG9yeSB2YXJpYWJsZSB0byBjaGVjayBpbmRlcGVuZGVuY2UKCioqSW5zdGVhZCBvZiBhIHZpc3VhbCBpbnNwZWN0aW9uLCBpdCBpcyBhbHNvIHBvc3NpYmxlIHRvIGFwcGx5IGEgdGVzdCBmb3IgaG9tb2dlbmVpdHkuIApTb2thbCBhbmQgUm9obGYgKDE5OTUpIGRlc2NyaWJlIHRocmVlIHN1Y2ggdGVzdHMsIG5hbWVseSAKMS4gdGhlIEJhcmxldHTigJlzIHRlc3QgZm9yIGhvbW9nZW5laXR5ICAqc2Vuc2l0aXZlIHRvIG5vbi1ub3JtYWxpdHkhIAoyLiBIYXJ0bGV54oCZcyBGbWF4IHRlc3QgYW5kIHRoZSBsb2ctYW5vdmEKMy4gU2NoZWZmZSDMgS1Cb3ggdGVzdAoKYGBge3J9CmhlbHAodC50ZXN0KQpgYGAKCgoKCg==